質問の意味:
あなたはn個、いくつかのマイナーな変更が可能休みの日にする増分はkの最大許容コストは文字列に現在の01日からお聞き++費用がかかります作業の連続作業日の残りの1のための01の長さの文字列のn 0をk個クマ。
アイデア:
メモリ検索:DFS(場所、巻数)
比較列挙は、逆方向電流POSに見出されるか、平日分DFS(次フリップカウントの現在位置 - 1)後に採取+コストのために必要な日数のこの期間
Sのうち場合列挙ループ[CUR] ==「0」またはCUR == Nの比較は分DFS(CUR、フリップ)+コストがかかり、それがDFSの各ので入る//理由場合CURないCUR + 1ここで、S [POS]議論
行き:
フリップ<0戻りINF。
POS == N + 1戻り0;
ANS [POS] [フリップ] == -1戻りANS [POS] [フリップ]。
S [POS] == '0' の戻りDFS(POS + 1、フリップは); // Aの下に行きます
ACコード:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
int n,k;
char s[505];
int ans[505][505];
int add(int x){
return x * (x + 1) / 2;
}
int dfs(int pos,int flip){
if(flip < 0) return inf;
if(pos == n + 1) return 0;
if(~ans[pos][flip]) return ans[pos][flip];
if(s[pos] == '0') return dfs(pos + 1,flip);//0
//无特殊情况 让我们开始寻找ans[pos][flip]吧!
ans[pos][flip] = inf;
int cur;
for(cur = pos ; cur <= n && s[cur] == '1' ; cur++){
ans[pos][flip] = min(ans[pos][flip],dfs(cur + 1,flip - 1) + add(cur - pos));
if(!ans[pos][flip]) return 0;
}
ans[pos][flip] = min(ans[pos][flip],dfs(cur,flip) + add(cur - pos));
return ans[pos][flip];
}
int main()
{
memset(ans,-1,sizeof ans);
scanf("%d %d",&n,&k);
scanf("%s",s + 1);
for(int i = 0;i <= n; i++){
if(dfs(1,i) <= k){ //从1开始 变换i个的代价可以承受
printf("%d\n",i);
break;
}
}
}