DP_紀念第一次寫出來dp

The sunshine。發表於2020-12-08

題意:

1154 迴文串劃分

有一個字串S,求S最少可以被劃分為多少個迴文串。
例如:abbaabaa,有多種劃分方式。

a|bb|aabaa - 3 個迴文串
a|bb|a|aba|a - 5 個迴文串
a|b|b|a|a|b|a|a - 8 個迴文串

其中第1種劃分方式的劃分數量最少。

輸入
輸入字串S(S的長度<= 5000)。

輸出
輸出最少的劃分數量。

輸入樣例
abbaabaa

輸出樣例
3

思路:

算了,對我這種菜雞來說,很友好的了。。
狀態:dp[i]表示前i個數劃分形成的迴文串的數量
狀態轉移:dp[i] = min(dp[k - 1] + 1,dp[i]);

外層迴圈:以i結尾。。
內層迴圈:如果[k , i]可以形成迴文串,那麼dp[i]可以由dp[k - 1] + 1轉移過來。。

程式碼實現:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
char s[maxn];
int dp[maxn];
bool check(int l,int r){
	for(int i = l,j = r;i <= j;i++,j--){
		if(s[i] != s[j]){
			return false;
		}
	}
	return true;
}
int main(){
	scanf("%s",s + 1);
	int len = strlen(s + 1);
	memset(dp,0,sizeof(dp));
	int ans = len;
	for(int i = 1;i <= len;i++) dp[i] = i;
	for(int i = 1;i <= len;i++){
		for(int k = 1;k <= i;k++){
			if(check(k,i)){
				dp[i] = min(dp[i],dp[k - 1] + 1);
			}
		}
	}
	printf("%d\n",dp[len]);
	return 0;
}

相關文章