poj3616(LIS简单变式)

 题目链接: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
",res);
27     return 0;
28 }
原文地址:https://www.cnblogs.com/FrankChen831X/p/10440409.html