[bzoj1090][SCOI2003]字符串折疊_區間dp
阿新 • • 發佈:2018-07-12
https .com print mar 狀態 好題 com sans i++
字符串折疊 bzoj-1090 SCOI-2003
題目大意:我說不明白...鏈接
註釋:自己看
想法:動態規劃
狀態:dp[i][j]表示從第i個字符到第j個字符折疊後的最短長度。
轉移:dp[l][r]=min(r-l+1,dp[l][k]+dp[k+1][r])
當k+1~r可以有l~k得到時還要
dp[l][r]=min(dp[l][r],dp[l][k]+2+calc((r-l+1)/(k-l+1)));//calc用來計算一個十進制數所占位數
最後,附上醜陋的代碼... ...
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char s[101]; int f[101][101]; bool mark[101][101]; bool jud(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 get(int x) { int t=0; while(x) { x/=10;t++; } return t; } int dp(int l,int r) { if(l==r)return 1; if(mark[l][r])return f[l][r]; mark[l][r]=1; int t=r-l+1; for(int i=l;i<r;i++) { t=min(t,dp(l,i)+dp(i+1,r)); if(jud(i+1,r,l,i)) t=min(t,dp(l,i)+2+get((r-i)/(i-l+1)+1)); } return f[l][r]=t; } int main() { scanf("%s",s); printf("%d",dp(0,strlen(s)-1)); return 0; }
小結:好題,就是那個十進制的太不要臉了.......
[bzoj1090][SCOI2003]字符串折疊_區間dp