思路
dp[i][j][k] 表示对于前i天一共工作了j天现在连续工作了k天的最小花费 滚动数组优化掉第一维(不然会MLE)
if(s[i]=='0') 为0只能休息
dp[j][0]=min(dp[j][0],dp[j][k])

if(s[i]=='1')
dp[j][0]=min(dp[j][0],dp[j][k]) 选择休息
dp[j][k]=min(dp[j][k],dp[j-1][k-1]+k) 选择工作

然后发现s[i]==1 选择休息和s[i]==0的转移方程一样
所以
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)

对于总共工作了j天 j这一层的循环需要倒序
因为是要么做 要么不做 效仿01背包 不然同一天可能会重复计算 最后要找的答案即最小花费≤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++){
                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);///选择工作
           }
        }
    }
    for(int i=n;i>=0;i--){
        for(int j=0;j<=i;j++){
            if(dp[i][j]<=k){
                  cout<<i<<endl;
                  return 0;
            }
        }
    }
}