UVA - 11552 Fewest Flops
Posted 人间失格
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA - 11552 Fewest Flops相关的知识,希望对你有一定的参考价值。
A common way to uniquely encode a string is by replacing its consecutive repeating characters (or “chunks”) by the number of times the character occurs followed by the character itself. For example, the string “aabbbaabaaaa” may be encoded as “2a3b2a1b4a”. (Note for this problem even a single character “b” is replaced by “1b”.) Suppose we have a string S and a number k such that k divides the length of S. Let S1 be the substring of S from 1 to k, S2 be the substring of S from k + 1 to 2k, and so on. We wish to rearrange the characters of each block Si independently so that the concatenation of those permutations S ′ has as few chunks of the same character as possible. Output the fewest number of chunks. For example, let S be “uuvuwwuv” and k be 4. Then S1 is “uuvu” and has three chunks, but may be rearranged to “uuuv” which has two chunks. Similarly, S2 may be rearranged to “vuww”. Then S ′ , or S1S2, is “uuuvvuww” which is 4 chunks, indeed the minimum number of chunks.
Input
The input begins with a line containing t (1 ≤ t ≤ 100), the number of test cases. The following t lines contain an integer k and a string S made of no more than 1000 lowercase English alphabet letters. It is guaranteed that k will divide the length of S.
Output
For each test case, output a single line containing the minimum number of chunks after we rearrange S as described above.
题解:
这个题目还算好写。
首先我们考虑一种简化的情况假设全部只有一组会怎么样?贪心的思考一下只要将所有的字母相同的放在一起,然后统计块数就可以了。那么如果用多个组结果是哪里不同呢?
如果我们把前一个组的最后一个块和当前组的最开始一个组放在一起(前提:颜色相同),那么数量就可以少一,思考到这状态就是显然的了!设dp[i][j]为dp到第i组并且当前这个组的最后一个块的颜色是i的最小花费。转移有两个一个不管怎样就是强行把所有的块塞到前一组的末尾——dp[i][j]=min(dp[i][j],dp[i-1][k]+num[i]),第二个转移,当前一组最后一个块的颜色和当前这组一种颜色相同时就可以把他们拼在一起,所以就只要加num[i]-1,即:dp[i][j]=min(dp[i][j],dp[i-1][k]+num[i]-1);有小细节,写的时候注意一下就可以了。
代码:
#include<iostream> #include<cstring> #include<algorithm> #include<stdio.h> #include<stdlib.h> #define MAXN 1010 using namespace std; int num[MAXN],have[MAXN][27]; int dp[MAXN][27]; char a[MAXN]; int n,k,tot; int main(){ int t;scanf("%d",&t); while(t--){ scanf("%d",&k),scanf("%s",a+1); n=strlen(a+1); memset(num,0,sizeof(num)); memset(have,0,sizeof(have)); memset(dp,127/3,sizeof(dp)); for(int i=1,hao=1;i<=n;i+=k,hao++) for(int j=i;j<i+k;j++){ if(!have[hao][a[j]-‘a‘]) num[hao]++; have[hao][a[j]-‘a‘]=1; } tot=n/k; for(int i=0;i<=25;i++) dp[0][i]=0; for(int i=1;i<=tot;i++) for(int j=0;j<=25;j++){ if(!have[i][j]) continue; for(int k=0;k<=25;k++) dp[i][j]=min(dp[i][j],dp[i-1][k]+num[i]); if(i!=1) for(int k=0;k<=25;k++){ if(have[i][k]==0) continue; if(k==j&&num[i]!=1) continue; dp[i][j]=min(dp[i][j],dp[i-1][k]+num[i]-1); } } int ans=1<<30; for(int i=0;i<=25;i++) ans=min(ans,dp[tot][i]); printf("%d\n",ans); } }
以上是关于UVA - 11552 Fewest Flops的主要内容,如果未能解决你的问题,请参考以下文章