1. 程式人生 > >DP練習1題解C

DP練習1題解C

DP練習1題解C

先上題目描述

在這裡插入圖片描述

需要記錄的狀態有時間 已經移動次數 當前在那棵樹下
很容易想到需要開一個三維陣列dp[i][j][k]
i:當前時間 j:已經移動次數 k:當前在那顆樹下
因為奶牛移動速度夠快(你真的是奶牛嗎)
我們可以讓奶牛稍微聰明下
他在當前所在樹掉果子時 不會傻乎乎跑到另一棵樹下(因為吃完再走也來得及)
因此狀態轉移方式也就是:
在某樹掉果子時 奶牛可能從隔壁樹跑過來 也可能就在底下等著
然後另外一棵樹下的狀態等於上一分鐘的
方程如下:(以1樹掉果子為例)
a[i][j][1]= max(a[i-1][j][1]+1,a[i-1][j-1][2]+1)
a[i][j][2]=a[i-1][j][2];
程式碼如下:

#include<iostream>
#include<cstring>
using namespace std;
int a[1001][31][3];
int d[1001];
int main()
{
 int t,w,i,j,max;
 while(cin>>t>>w)
 {
 memset(a,0,sizeof(a)); 
 for (i=1;i<=t;i++)
 {
  cin>>d[i];
  a[i][0][1]=a[i-1][0][1];
  a[i][0][2]=0;
  a[i][0][d[i]]++;
 }
 for (i=1;i<=t;i++)
 for (j=1;j<=w;j++)
 {
  if (d[i]==1)
  {
   max=a[i-1][j][1]+1;
   if (a[i-1][j-1][2]+1>max) max=a[i-1][j-1][2]+1;
   a[i][j][1]=max;
   a[i][j][2]=a[i-1][j][2];
  }
  else
  {
   max=a[i-1][j][2]+1;
   if (a[i-1][j-1][1]+1>max) max=a[i-1][j-1][1]+1;
   a[i][j][2]=max;
   a[i][j][1]=a[i-1][j][1];
  }
 }
 max=0;
 for (j=0;j<=w;j++)
 {
  if (a[t][j][1]>max) max=a[t][j][1];
  if (a[t][j][2]>max) max=a[t][j][2];
 }
 cout<<max<<endl;
}
 return 0;
}

以上