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 }
View Code

 

1270: [BeijingWc2008]雷涛的小猫

Time Limit: 50 Sec  Memory Limit: 162 MB
Submit: 1101  Solved: 543
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

Sample Output

8

HINT

Source

posted @ 2016-05-25 18:54  晴歌。  阅读(301)  评论(0编辑  收藏  举报