UVA11552:Fewest Flops

发现如果只有一块就是种类的数目,也就是同种放在一起,

再考虑多块,如果违背的上面的规律,可以发现不会更优,

于是问题就是求在满足同种类放在一起的前提下,尽量使得相邻块的两端一模一样

然后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
",ans);
}
int main()
{
//    freopen("data.in","r",stdin);
//    freopen("my.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--){
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/w-h-h/p/7853670.html