20191005-T3-U91353 放射性

传送门:https://www.luogu.org/problem/U91353

这道题,我太弱了QWQ,爆搜过两个点走人......

先想想,这道题一眼DP,但是状态想出来了,决策就不会了,这道题的决策依赖于贪心

把每个点的按T[i]/L[i] 从小到大排序,然后当一个背包做。(!!!判断合法状态!!!)

贪心证明可以考虑临项交换。(不在证明(

还有一点就是背包的体积要开多少?

如果超过最大的E[i]就没用了。想想为什么?

最小的L[i]也有1  (为0的可以直接统计到答案,那是白给的)  所以不会超过max{E[i]}

#include<cstdio>
#include<algorithm>
#include<cstring>
#define R register
using namespace std;
int T,n,cnt,ans,sum,dp[21000];
struct ddd{
    int e,l,t;
}p[120];
inline bool com(ddd a,ddd b){
    return a.t*b.l<=b.t*a.l;
}
int main (){
    scanf("%d",&T);
    while(T--){
        ans=0,sum=0,cnt=0;
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(R int i=1;i<=n;i++){
            cnt++;
            scanf("%d%d%d",&p[cnt].e,&p[cnt].l,&p[cnt].t);
            if(p[cnt].l==0) sum+=p[cnt].e,cnt--;
        }
        sort(p+1,p+1+cnt,com);
        for(R int i=1;i<=cnt;i++){
            for(R int j=20000;j>=p[i].t;j--){
                dp[j]=max(dp[j],(p[i].e-p[i].l*(j-p[i].t))>=0? dp[j-p[i].t]+(p[i].e-p[i].l*(j-p[i].t)):0 );
            }
        }
        for(R int i=1;i<=20000;i++) ans=max(ans,dp[i]);
        printf("%d
",ans+sum);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/coclhy/p/11643490.html