[HDU] 1881 毕业bg - 先通过排序的方式消除后效性
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1881
方法:设F(i,n)为当考察到第i个bg,在第n天的时候,能获取的最大快乐,当然该bg要对一天获得的快乐度产生影响,则必须要第i个bg的结束时间i_deadLine小于等于n,已经当天减去其持续时间i_duration,设每个bg的快乐度是i_pleasure,bg的数量为count,状态转移方程如下:
F(i,n) = Max(F(i,n-i_duration)+i_pleasure, F(i,n)) , n<= i_deadLine and n-i>=0;
对每一个bg都做以上的考虑去跟新第x天的最大快乐度,当所有的bg都考虑了,选出快乐度最大的那天的快乐作为结果,所以以上方程来表示解就是 :
Max({F(count,x) | 0<=x<=Max({bg's deadLine})})
感谢:仔细体会为什么要贪心初始化。
代码:
View Code
#include<iostream> #include<math.h> #include<algorithm> using namespace std; int const MAX =0x3f3f3f3f; struct BG { int pleasure; int duration; int deadLine; }; bool cmp(BG x, BG y) { if(x.deadLine<y.deadLine) return true; return false; } int main() { int count; BG bgs[31]; int dp[1000]; while(scanf("%d",&count) && count>=0 ) { for(int i=0;i<count;i++) scanf("%d %d %d",&bgs[i].pleasure,&bgs[i].duration,&bgs[i].deadLine); sort(bgs,bgs+count,cmp); memset(dp,0,sizeof(dp)); for(int i=0;i<count;i++) for(int j = bgs[i].deadLine;j-bgs[i].duration>=0;j--) dp[j] = dp[j] < dp[j-bgs[i].duration]+bgs[i].pleasure ? dp[j-bgs[i].duration]+bgs[i].pleasure: dp[j] ; int x=-1; for(int i =1;i<=bgs[count-1].deadLine;i++) x = dp[i]>x ? x=dp[i]:x; cout<<(x==-1 ? 0 :x)<<endl; } return 0; }