uva Fewest Flops(dp)@

来源:互联网 发布:mac删除下载的软件 编辑:程序博客网 时间:2024/05/21 17:12

Fewest Flops

2000ms
131072KB
This problem will be judged on UVA. Original ID: 11552
64-bit integer IO format: %lld      Java class name: Main
Prev Submit Status Statistics Discuss Next
Font Size:  
Type:  

[PDF Link]

Problem F

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 tokS2 be the substring of S from + 1 to 2k, and so on. We wish to rearrange the characters of each block Siindependently 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 be “uuvuwwuv” and be 4. Then S1 is “uuvu” and has three chunks, but may be rearranged to “uuuv” which has two chunks. Similarly, Smay be rearranged to “vuww”. Then S’, or S1S2, is “uuuvvuww” which is 4 chunks, indeed the minimum number of chunks.

Program Input

The input begins with a line containing (1 ≤ ≤ 100), the number of test cases. The following lines contain an integerand a string S made of no more than 1000 lowercase English alphabet letters. It is guaranteed that k will divide the length of S.

Program Output

For each test case, output a single line containing the minimum number of chunks after we rearrange S as described above.

INPUT

25 helloworld7 thefewestflops
OUTPUT
810


给你一个字符串,长度为k的整数倍,要你分成每个长度为k的段 每个段内可以重新编排,连续的几个字母看作一个块问最少有几个块

解:枚举每一个段中的K个字符谁当末尾,然后贪心选择,dp[i][j]表示,第i段第j个字符做末尾时的最小块


#include <iostream>#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e6+7;const int inf = 0x3f3f3f3f;const LL mod  = 10000007;char str[1100];int vis[1100], dp[1007][1007];int main(){    int t;    scanf("%d", &t);    while(t--)    {        int k;        scanf("%d %s",&k, str);        int len=strlen(str);        memset(dp,0x3f3f3f3f,sizeof(dp));        for(int l=1; l<=(len/k); l++)        {            memset(vis,0,sizeof(vis));            for(int i=1; i<=k; i++)            {                int pre=(l-1)*k+i-1;                vis[str[pre]]++;            }            int cnt=0;            for(int i='a'; i<='z'; i++)                if(vis[i]) cnt++;            if(l==1)            {                for(int i=1;i<=k;i++)  dp[1][i]=cnt;                continue;            }            for(int i=1;i<=k;i++)            {                int rear=(l-1)*k+i-1;                for(int j=1;j<=k;j++)                {                    int pre=(l-2)*k+j-1;                    if(vis[str[pre]]&&(str[pre]!=str[rear]||cnt==1)) dp[l][i]=min(dp[l][i],dp[l-1][j]+cnt-1);                    else dp[l][i]=min(dp[l][i],dp[l-1][j]+cnt);                }            }        }        int ans=0x3f3f3f3f;        for(int i=1;i<=k;i++) ans=min(ans,dp[len/k][i]);        cout<<ans<<endl;    }    return 0;}

0 0
原创粉丝点击