ジム-101875E Loppinha、sopinhaが好きな男の子

質問の意味:

あなたは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;
		}
	}
}

 

公開された31元の記事 ウォンの賞賛5 ビュー1371

おすすめ

転載: blog.csdn.net/qq_43685900/article/details/102756777