Fewest Flops
64-bit integer IO format: %lld Java class name: Main
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 tok, S2 be the substring of S from k + 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 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.
Program Input
The input begins with a line containing t (1 ≤ t ≤ 100), the number of test cases. The following t lines contain an integerk 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.
Program Output
For each test case, output a single line containing the minimum number of chunks after we rearrange S as described above.
INPUT
2 5 helloworld 7 thefewestflops
OUTPUT
8 10
给你一个字符串,长度为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;
}