BZOJ_1270_雷涛的小猫_(动态规划)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1270
有n棵树,高度为h.一只猫从任意一棵树的树顶开始,每次在同一棵树上下降1,或者跳到其他树上同时下降d.它经过的地方的果子都会被吃掉,求落地前最多吃多少果子.
分析
高度低的位置的值肯定是由高度高的位置更新得来的.在某一位置,有两种可能:
1.是从这个树上下降1到达这里的.
2.是从其他树上跳来的.由于可以从任意树上跳来,所有选之前吃果子最多的树.
用dp1[i][j]表示到达第i棵树,高度j的时候的最优解.那么:
dp1[i][j]=max(dp1[i][j-1],dp2[j-d])+a[i][j].
其中dp2[x]表示到达高度x时的最优解,a[i][j]表示第i棵树上,高度j位置的果子数量.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=5000+5,maxh=2000+5; 5 int n,h,d,ans; 6 int dp1[maxn],dp2[maxh]; 7 int a[maxn][maxh]; 8 9 void solve(){ 10 for(int i=h;i>=1;i--){ 11 for(int j=1;j<=n;j++){ 12 if(i+d<=h&&dp2[i+d]>dp1[j]) dp1[j]=dp2[i+d]; 13 dp1[j]+=a[j][i]; 14 dp2[i]=max(dp2[i],dp1[j]); 15 } 16 ans=max(ans,dp2[i]); 17 } 18 printf("%d\n",ans); 19 } 20 int main(){ 21 scanf("%d%d%d",&n,&h,&d); 22 for(int i=1;i<=n;i++){ 23 int t; scanf("%d",&t); 24 while(t--){ 25 int k; scanf("%d",&k); 26 a[i][k]++; 27 } 28 } 29 solve(); 30 return 0; 31 }
1270: [BeijingWc2008]雷涛的小猫
Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 1101 Solved: 543
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
8