題面
【題目描述】
很少有人知道奶牛愛喫蘋果.農夫約翰的農場上有兩棵蘋果樹(編號爲和),每一棵樹上都長滿了蘋果.奶牛貝茜無法摘下樹上的蘋果,所以她只能等待蘋果從樹上落下.但是,由於蘋果掉到地上會摔爛,貝茜必須在半空中接住蘋果(沒有人愛喫摔爛的蘋果).貝茜喫東西很快,所以她接到蘋果後僅用幾秒鐘就能喫完.每一分鐘,兩棵蘋果樹其中的一棵會掉落一個蘋果.貝茜已經過了足夠的訓練,只要站在樹下就一定能接住這棵樹上掉落的蘋果.同時,貝茜能夠在兩棵樹之間快速移動(移動時間遠少於1分鐘),因此當蘋果掉落時,她必定站在兩棵樹其中的一棵下面.此外,奶牛不願意不停地往返於兩棵樹之間,因此會錯過一些蘋果, 蘋果每分鐘掉落一個,共分鐘,貝茜最多願意移動次.
現給出每分鐘掉落蘋果的樹的編號,要求判定貝茜能夠接住的最多蘋果數.開始時貝茜在號樹下.
【輸入】
第行:由空格隔開的兩個整數和.
第到行:或(每分鐘掉落蘋果的樹的編號).
【輸出】
在貝茜移動次數不超過W的前提下她能接到的最多蘋果數
【樣例輸入】
7 2
2
1
1
2
2
1
1
【樣例輸出】
6
【樣例解釋】
分鐘內共掉落個蘋果一一第個從第棵樹上掉落,接下來的個蘋果從第棵樹上掉落,再接下來的個從第棵樹上掉落,最後個從第棵樹上掉落.
貝茜不移動直到接到從第棵樹上掉落的兩個蘋果,然後移動到第棵樹下,直到接到從第棵樹上掉落的兩個蘋果,最後移動到第棵樹下,接住最後兩個從第棵樹上掉落的蘋果.這樣貝茜共接住個蘋果.
算法分析
我們需要知道貝西當前在在一棵樹下,使用了多少次移動次數,當前的時間。那麼就定義一個數組表示這些信息:
狀態:
——分鐘,移動次,此時在第棵樹下得到的最多蘋果數。
狀態轉移方程:
考慮第分鐘時,是否進行移動,移動到哪一棵樹下。
爲了寫代碼方便,使用數組表示分鐘第棵蘋果樹掉落的蘋果,表示分鐘第棵蘋果樹掉落的蘋果,當前在第棵蘋果樹下,移動就會移動到第棵蘋果數下。
分兩種情況:
不移動:,
移動:
取一個值。
時間複雜度:
參考程序
#include<bits/stdc++.h>
#define N 1010
using namespace std;
int n,m;
int a[2][N]; //a[0]爲第一棵樹,a[1]爲第二棵樹
int f[N][33][2]; //f[t][i][j],t分鐘,移動i次,在第j棵樹下
int main()
{
scanf("%d%d",&n,&m);
int x;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x==1) a[0][i]=1;
else a[1][i]=1;
}
int ans=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=1;j++)
f[0][i][j]=0;
for(int t=1;t<=n;t++)
for(int i=0;i<=m;i++)
for(int j=0;j<=1;j++)
{
if(i==0)
f[t][i][j]=f[t-1][i][j]+a[j][t];
else
f[t][i][j]=max(f[t-1][i][j]+a[j][t],f[t-1][i-1][(j+1)%2]+a[(j+1)%2][t]);//不移動或者移動
if(t==n) ans=max(f[n][i][j],ans);
}
cout<<ans<<endl;
return 0;
}