Rabbit的工作(1) (dP)

题目:题目链接
  • 一个人工作时越工作越累,连续工作k天每天消耗体力为k,并且他最多消耗m的体力,当他休息一天后就可以恢复所有体力。在公司工作,给出一个字符01串,s[i]=0时表示第i天公司放假,他休息。s[i]=1时他可以自由选择休息还是工作。问这个人最多工作多少天?

  • dp题。用dp[i][j][k]表示前i天工作j天且最近连续工作k天的最小花费。s[i]=0时,dp[i][j][0]=min(dp[i][j][0], dp[i-1][j][k]); s[i]=1时,dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][k]),dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-1][k-1]+k);当然要滚动数组优化一下。最后找到dp[j][k]<=m的最大的j就是答案。


int n, m, T;
int dp[N][N];
char s[N];

int main(){
    scanf("%d%d",&n,&m);
    scanf("%s", s + 1);
    
    memset(dp, 0x3f, sizeof(dp));
    dp[0][0] = 0;
    for(int i  = 1; i <= n; ++ i){
        for(int j = i; j >= 1; -- j){
            for(int k = 1; k <= j; ++ k){
                dp[j][0] = min(dp[j][0], dp[j][k]);
                if(s[i] == '1') dp[j][k] = min(dp[j][k], dp[j - 1][k - 1] + k); 
            }
        }
    }
    int res =  0;
    for(int j  = n; j >= 0; -- j){
        for(int k  = 0; k <= j; ++ k){
            if(dp[j][k] <= m){
                printf("%d
",j);
                return 0;
            }
        }
    }
    printf("%d
",res);
    return 0;
}
原文地址:https://www.cnblogs.com/A-sc/p/12928287.html