[SCOI2003]字符串折叠
生活随笔
收集整理的這篇文章主要介紹了
[SCOI2003]字符串折叠
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[SCOI2003]字符串折疊
時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld題目描述
折疊的定義如下:
一個字符串可以看成它自身的折疊。記作S = S X(S)是X(X>1)個S連接在一起的串的折疊。記作X(S) = SSSS…S(X個S)。
如果A = A’, B = B’,則AB = A’B’ 例如,因為3(A) = AAA, 2(B) = BB,所以3(A)C2(B) =
AAACBB,而2(3(A)C)2(B) = AAACAAACBB
給一個字符串,求它的最短折疊。例如AAAAAAAAAABABABCCD的最短折疊為:9(A)3(AB)CCD。
輸入描述:
僅一行,即字符串S,長度保證不超過100。
輸出描述:
僅一行,即最短的折疊長度。
示例1
輸入
復制
輸出
復制
題解:
菜。。。我太菜了
dp[l][r]表示l~r的最短折疊長度
dp[l][r]=min(r-l+1,dp[l][k]+dp[k+1][r]) l<=k<r
當區間[k+1,r]可以由區間[l,k]重復時,dp[l][r]=min(dp[l][r],dp[l][k]+2+calc((r-l+1)/(k-l+1))
2是指 括號 占的位數
calc是指系數所占位數
最終答案是dp[0][len-1]
代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=140; int dp[maxn][maxn]; bool vis[maxn][maxn]; char s[maxn]; bool check(int l,int r,int cl,int cr) {if((r-l+1)%(cr-cl+1)!=0)return false;for(int i=l;i<=r;i++){if(s[i]!=s[(i-l)%(cr-cl+1)+cl])return false;}return true; } int calc(int x)//x是幾位數 {int ans=0;while(x){x/=10;ans++;} return ans; }int dfs(int l,int r) {if(l==r)return 1;if(vis[l][r])return dp[l][r];vis[l][r]=true;dp[l][r]=r-l+1;for(int i=l;i<r;i++){dp[l][r]=min(dp[l][r],dfs(l,i)+dfs(i+1,r));if(check(i+1,r,l,i)){dp[l][r]=min(dp[l][r],dfs(l,i)+2+calc((r-i)/(i-l+1)+1));}}return dp[l][r]; } int main() {//cin>>s;scanf("%s",s); int sum=dfs(0,strlen(s)-1);cout<<sum; }總結
以上是生活随笔為你收集整理的[SCOI2003]字符串折叠的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lucid Air 车型推出反向充电功能
- 下一篇: 【每日一题】7月16日题目精讲—点权和