题目链接:http://poj.org/problem?id=3616
思路:
我的第一反应是背包,因为每个interval要么选择要么不选,后来发现状态方程很难写出来。后来想一想发现就是LIS的简单变式。先按照starting hours给数据排序,那么选择的顺序也就是排序后的顺序,用dp[i]表示以第i个interval结尾能获得最多的milk,状态转移方程就是dp[i]=max(dp[i],dp[j]+a[i].c)(a[j].e+r<=a[i].s,j<i)。由于上升子序列的长度最长的不一定是milk最多的,所以需要使用LIS的O(n^2)算法。另外记住需要初始化dp,即dp[i]=a[i].c。最后选择最大的dp[i],就是所求答案。
详见代码:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 struct node{ 6 int s,e,c; 7 }a[1005]; 8 9 bool cmp(node x,node y){ 10 return x.s<y.s; 11 } 12 int n,m,r,res,dp[1005]; 13 14 int main(){ 15 scanf("%d%d%d",&n,&m,&r); 16 for(int i=1;i<=m;++i) 17 scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].c); 18 sort(a+1,a+m+1,cmp); 19 for(int i=1;i<=m;++i) dp[i]=a[i].c; 20 for(int i=2;i<=m;++i){ 21 for(int j=i-1;j>=1;--j) 22 if(a[j].e+r<=a[i].s) 23 dp[i]=max(dp[i],dp[j]+a[i].c); 24 if(dp[i]>res) res=dp[i]; 25 } 26 printf("%d\n",res); 27 return 0; 28 }