Rabbit的工作(1)

Rabbit的工作(1)

思路:對於是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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章