费用报销--01背包+分组背包---记忆化dp
【代码】费用报销--01背包+分组背包---记忆化dp。
·
https://www.luogu.com.cn/record/211325661
根据状态转移方程,前面不选,后面选
选定位到last,因为前面已经被最优覆盖了,所以last对应一定最优
#include<bits/stdc++.h>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<ll,int> pii;
int n,m,k;
int mn[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
struct day
{
int d;
int v;
}da[1005];
int last[1005];
int dp[1005][5011];
int dd(int a,int d)
{
int r=d;
for(int i=1;i<a;i++)
{
r+=mn[i];
}
return r;
}
bool cmp(struct day a,struct day b)
{
return a.d<b.d;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
int a;int b;
cin>>a>>b>>da[i].v;
da[i].d=dd(a,b);///转换成天
}
sort(da+1,da+1+n,cmp);///时间排序
for(int i=1;i<=n;i++)
{
for(int j=i-1;j>=0;j--)
{
if(da[i].d-k>=da[j].d)
{
last[i]=j;///取满足i的最后一个
break;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=da[i].v;j--)
{
dp[i][j]=max(dp[i-1][j],dp[last[i]][j-da[i].v]+da[i].v);///前面不选,后面选,last是若选定位到
///最后一个可以选的
///由于前面已经覆盖了,所以last对应就是最犹
}
}
cout<<dp[n][m];
}
更多推荐



所有评论(0)