标签:print 问题 include fine name for ace using i++
发现如果只有一块就是种类的数目,也就是同种放在一起,
再考虑多块,如果违背的上面的规律,可以发现不会更优,
于是问题就是求在满足同种类放在一起的前提下,尽量使得相邻块的两端一模一样
然后dp一下就可以了
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define MAXN 1005 using namespace std; int n,k; char s[MAXN]; int b[MAXN][30]; int len[MAXN]; int dp[MAXN][30]; void solve(){ memset(dp,0x3f,sizeof(dp)); memset(b,0,sizeof(b)); memset(len,0,sizeof(len)); scanf("%d",&k); scanf("%s",s); n=strlen(s); for(int i=0;i<n;i+=k){ for(int j=i;j<=i+k-1;j++){ if(!b[i/k][s[j]-96]){ len[i/k]++; } b[i/k][s[j]-96]=1; } } for(int i=1;i<=26;i++){ if(b[0][i]) dp[0][i]=len[0]; } for(int i=1;i<n/k;i++){ for(int j=1;j<=26;j++){ if(b[i][j]){ for(int s=1;s<=26;s++){ if(b[i-1][s]){ dp[i][j]=min(dp[i][j],dp[i-1][s]-(b[i][s]&&(len[i]==1||j!=s))); } } dp[i][j]+=len[i]; } } } int ans=0x7f7f7f7f; for(int i=1;i<=26;i++){ ans=min(ans,dp[(n/k)-1][i]); } printf("%d\n",ans); } int main() { // freopen("data.in","r",stdin); // freopen("my.out","w",stdout); int T; scanf("%d",&T); while(T--){ solve(); } return 0; }
标签:print 问题 include fine name for ace using i++
原文地址:http://www.cnblogs.com/w-h-h/p/7853670.html