标签:一段 inf -- names tin play click isp continue
题意:输入一个字符串(l<=1000),一个n,把字符串分为l/n段,每一段内部可以进行重排列,问最少有就几个连续的段比如2 abab答案是3
题解:简单dp,dp[i][j]代表第i段结尾是j的最少段数
#include <bits/stdc++.h> #define maxn 1100 #define INF 0x3f3f3f3f typedef long long ll; using namespace std; char s[maxn]; int num[maxn], dp[maxn][30], mp[maxn][30]; int main(){ int T, x, n, l, ans; scanf("%d", &T); while(T--){ scanf("%d", &x); scanf("%s", s); l = strlen(s); n = l/x; memset(mp, 0, sizeof(mp)); memset(num, 0, sizeof(num)); memset(dp, INF, sizeof(dp)); for(int i=0;i<l;i++){ if(mp[i/x][s[i]-‘a‘] == 0) num[i/x]++; mp[i/x][s[i]-‘a‘]++; } for(int i=0;i<=25;i++) if(mp[0][i]){ dp[0][i] = num[0]; } for(int i=1;i<n;i++){ for(int k=0;k<=25;k++){ if(mp[i-1][k] == 0) continue; for(int j=0;j<=25;j++){ if(mp[i][j] == 0) continue; for(int t=0;t<=25;t++){ if(mp[i][t] == 0) continue; if(t==j&&num[i]!=1) continue; if(k == t) dp[i][j] = min(dp[i][j], dp[i-1][k]+num[i]-1); else dp[i][j] = min(dp[i][j], dp[i-1][k]+num[i]); } } } } ans = INF; for(int i=0;i<=25;i++){ ans = min(ans, dp[n-1][i]); } printf("%d\n", ans); } return 0; }
标签:一段 inf -- names tin play click isp continue
原文地址:http://www.cnblogs.com/Noevon/p/7650414.html