解:
其实我们可以发现有几块土地,和这道题目根本没什么关系,一种植物肯定比多种植物要优,所以我们就当一块土地来做,最后再把钱乘以土地数量就好了。
然后就是一个和背包很像的动归加个二分,在程序注释里解释好了。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m,t,k,a[5009],ti[5009],p[5009],f[5009]; int find(int x) //二分找时间 { int l=0,r=k,ans=0; while (l<=r) { int mid=(l+r)/2; if (a[mid]<=x) { ans=mid; l=mid+1; } else r=mid-1; } return ans; } int main() { scanf("%d%d%d%d",&n,&m,&t,&k); int x,y; for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&ti[i],&y); p[i]=y-x;//每种植物能赚的钱 } for (int i=1;i<=k;i++) scanf("%d",&a[i]); sort(a+1,a+1+k); //这里一定要排序,因为输入的时间不一定有序 f[1]=0; //f[i]表示第i次上线时能赚的最多的钱 for (int i=2;i<=k;i++) { for (int j=1;j<=m;j++) if (a[i]-ti[j]>=0) { int now=find(a[i]-ti[j]); //找到如果要在第i次上线时收获j这种植物,那么最迟要在第now次种下 if (now==0) continue; //如果没法上线,就退出 f[i]=max(f[i],f[now]+p[j]); //更新答案 } } printf("%d\n",f[k]*n); return 0; }