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];
}

Logo

集算法之大成!助力oier实现梦想!

更多推荐