思路:對於是0的位置直接選擇休息,對於是1的位置要麼工作,要麼休息,二選一的問題,有點像01揹包的選或者不選的問題,所以考慮效仿01揹包。答案是要求最多共工作了幾天,那麼開一個維度表示共工作了幾天,因爲此題跟連續工作的天數有關,所以我們需要加一個維度表示目前爲止連續工作的天數。
那麼也就是三個維度 dp[i][j][k]表示對於前i天一共工作了j天目前已經連續工作了k天的最小體力花費
此題空間給了64M 開三維會MLE 因爲很像01揹包 所以考慮滾動數組優化掉第一個維度
然後注意對於1的位置是選或者不選 也就是第二維度這裏 我們應該倒序遍歷,否則本來每個1只能最多工作一天 這樣會導致工作很多天 不太明白的考慮一下01揹包的倒序遍歷即可
那麼最後只要找dp[j][k]≤k的最大的j即爲所求答案
#include<bits/stdc++.h>
using namespace std;
int dp[505][505];
char s[505];
int main()
{
int n,k;
cin>>n>>k;
cin>>s+1;
memset(dp,0x3f,sizeof dp);
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=i;j;j--){///倒序
for(int k=1;k<=j;k++){
if(s[i]=='0'){///必須休息
dp[j][0]=min(dp[j][0],dp[j][k]);
}
else///可以工作可以休息
{
dp[j][0]=min(dp[j][0],dp[j][k]);///選擇休息
dp[j][k]=min(dp[j][k],dp[j-1][k-1]+k);///選擇工作
}
}
}
}
int m=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(dp[i][j]<=k) m=i;
}
}
cout<<m<<endl;
return 0;
}