アイデア:
3次元のdpを設定します。dp[i] [j] [k] dp [i] [j] [k]d p [ i ] [ j ] [ k ]到第ii私が働いているJJをこれまでj日、jjを含む私は j日kkで継続的に働きましたk日で消費される最小体力。
転送する方法は?
ときIIi日に休む必要がある場合、つまり、s [i] = = 0 s [i] == 0s [ i ]==0
- dp [i] [j] [0] = = dp [i − 1] [j] [k] dp [i] [j] [0] == dp [i-1] [j] [k] d p [ i ] [ j ] [ 0 ]==d p [ i−1 ] [ j ] [ k ](其中1 <= k <= j 1 <= k <= j1<=k<=j);
当第 i i i日間の休憩または休憩がない場合、つまり、s [i] = = 1 s [i] == 1s [ i ]==1
- 休息:dp [i] [j] [0] = dp [i − 1] [j] [k] dp [i] [j] [0] = dp [i-1] [j] [k]d p [ i ] [ j ] [ 0 ]=d p [ i−1 ] [ j ] [ k ](其中1 <= k <= j 1 <= k <= j1<=k<=j);
- 不休息:dp [i] [j] [k] = min(dp [i] [j] [k]、dp [i-1] [j-1] [k-1] + k)dp [i] [j] [k] = min(dp [i] [j] [k]、dp [i-1] [j-1] [k-1] + k)d p [ i ] [ j ] [ k ]=m i n (d p [ i ] [ j ] [ k ] 、d p [ i−1 ] [ j−1 ] [ k−1 ]+k ) ;
この質問にはスペースの制限があるため、スペースを圧縮する必要があります。01バックパックの圧縮スペースのアイデアを使用して、最初の次元を削除し、jjjは逆の順序でたどることができ、複雑度はo(n ∗ n ∗ n)o(n * n * n)です。o (n∗ん∗n )。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 500,inf = 1e9+20;
int dp[maxn][maxn];
int main()
{
int n,k;
cin >> n >> k;
string s;
cin >> s;
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)dp[i][j] = inf;
dp[0][0] = 0;
for(int i=1;i<=n;i++)
{
for(int j = i; j > 0; j--)
{
for(int k = 1; k <= j; k++)
{
if(s[i-1] == '0')dp[j][0] = min(dp[j][k],dp[j][0]);
else
{
dp[j][0] = min(dp[j][0],dp[j][k]);
dp[j][k] = min(dp[j][k] , dp[j-1][k-1] + k);
}
}
}
}
for(int i=n;i>0;i--)
for(int j=1;j<=n;j++)
if(dp[i][j] <= k)
{
cout<<i<<'\n';
return 0;
}
puts("0");
return 0;
}