码迷,mamicode.com
首页 > 其他好文 > 详细

UVA - 11552 Fewest Flops

时间:2017-08-31 16:15:38      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:cut   code   sim   ++   chunk   each   occurs   aaa   com   

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

标签:cut   code   sim   ++   chunk   each   occurs   aaa   com   

原文地址:http://www.cnblogs.com/renjianshige/p/7458318.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!