poj 2385
题目大意:有两颗苹果树,每一秒会有一颗掉落一个苹果(一共n秒),问在限制最多转换(从一颗走到另一颗)m次下最多能得到多少苹果。
分析:
dp[i][j][k]表示第i秒转换了j次当前在第k棵树下得到的苹果数最大值
显然只与上一秒的状态有关
dp[i][j][k]=max{dp[i-1][j][k],dp[i-1][j-1][1-k]}+a[i][k] {a[i][k]表示第i秒第k棵树是否有苹果}
那么答案就是max{dp[n][j][k]}
空间上可以优化,可以把第一维拿掉只要保证i是从小到大枚举的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 #include <algorithm> 6 #include <map> 7 #include <queue> 8 #include<vector> 9 #include <cmath> 10 #define maxn 1010 11 #define maxm 1000000 12 #define mod 1000000000 13 #define INF 0x3f3f3f3f 14 using namespace std; 15 int dp[maxn][40][2]; 16 int n,m; 17 int a[maxn][2]; 18 int main (){ 19 while(cin>>n>>m){ 20 for(int i=1;i<=n;++i){ 21 int x; 22 cin>>x; 23 a[i][x-1]=1; 24 a[i][2-x]=0; 25 } 26 dp[0][0][0]=0; 27 dp[0][0][1]=0; 28 for(int i=1;i<=n;++i){ 29 dp[i][0][0]=dp[i-1][0][0]+a[i][0]; 30 dp[i][0][1]=dp[i-1][0][1]+a[i][1]; 31 } 32 for(int i=1;i<=n;++i){ 33 for(int j=1;j<=m;++j){ 34 dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j-1][1])+a[i][0]; 35 dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0])+a[i][1]; 36 } 37 } 38 int ans=0; 39 for(int i=0;i<=m;++i){ 40 for(int j=0;j<2;++j){ 41 ans = max(ans,dp[n][i][j]); 42 } 43 } 44 cout<<ans<<endl; 45 } 46 }