UVA 11552 Fewest Flops

原创 2016年08月29日 23:36:02

题目链接:http://acm.hust.edu.cn/vjudge/problem/28550


题意:将字符串每k个字符分为一组(长度为k的倍数),每组内字符可以任意重排,使得重排之后的字符串包含尽量少的块,每个块为连续的相同字母。


思路:dp[i][j]表示前i个块,且第i个块以j字符结束时的最小块数。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007
const int maxn = 1009;

int T,k,n;
char s[maxn];
int kind[maxn]; //每个块内的字符种类
vector<int> p[maxn];  //块内字符
bool g[maxn][27]; //第i个块是否含有j
int dp[maxn][27];

void init()
{
    bool flag[30];
    int len = strlen(s+1);
    n = len / k;
    int pos = 0;
    Clean(g,false);
    rep(i,1,n)
    {
        kind[i] = 0;
        p[i].clear();
        p[i].push_back(0);
        Clean(flag,true);
        rep(j,1,k)
        {
            int x = s[++pos] - 'a' + 1;
            if ( flag[x] ) kind[i]++ , flag[x] = false , p[i].push_back(x);
            g[i][x] = true;
        }
    }
}

void solve()
{
    Clean(dp,0x3f);
    rep(i,1,kind[1])
        dp[1][i] = kind[1];

    rep(i,2,n)
    {
        rep(j,1,kind[i])
        rep(k,1,kind[i-1])
        {
            if ( ( g[i][p[i-1][k]] && p[i][j] != p[i-1][k] ) || ( kind[i] == 1 && p[i][j] == p[i-1][k] ) ) //有相同的字符,放在一起
                dp[i][j] = min( dp[i][j] , dp[i-1][k] + kind[i] - 1 );
            else
                dp[i][j] = min( dp[i][j] , dp[i-1][k] + kind[i] );
        }
    }
    int ans = inf;
    rep(i,1,kind[n])
        ans = min( ans , dp[n][i] );
    cout<<ans<<endl;
}

int main()
{
    cin>>T;
    while(T--)
    {
        scanf("%d %s",&k,s+1);
        init();
        solve();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

UVA 11552 Fewest Flops

题意:给出一个字符串s和一个整数k,s的长度是k的整数倍,把字符串从左到右每k个字符划分成一段,每一段的字符可以随意交换,最后再把这些段按原来的顺序拼接起来,要求排序后的字符串包含的块最少,块代表连续...

UVa:11552 - Fewest Flops

动态规划。 dp【i】【j】【k】表示前i组中,第i组以j开头以k结束时的最小组数。 这样取a【j】=min{dp【i-1】【k】【j】},该组内块数为val 则dp【i】【k】【q】=if k...

uva 11552 Fewest Flops

题意:把一个字符串每k个分成一组,组内可以任意排列,然后相同字母在一起为一块,最少多少块。 思路:组内必然是一起的排一起,不用考虑,然后我们用d[i][v]表示第i块用v做最后一个字符有多少块。 ...

UVA 11552-Fewest Flops(DP)

题目大意:给出只含小写字符的字符串,长度能被k整除,现在每k个字符分成一组,每组内可以随意排列。连续相同字符组成的子串称为一块,例如aabccc有3块,求分组每组内重排之后的最少块数。 用d...

uva 11552 Fewest Flops 线性dp

// uva 11552 Fewest Flops // // 二维线性dp // // 首先,块内肯定是相同的字母放在一起,先记录下每个块内有多少种字母 // 记作counts[i]; // //...

Uva 11552 - Fewest Flops 字符串dp

Problem F FEWEST FLOPS A common way to uniquely encode a string is by replacing its consecut...

uva 11552 dp专题I题

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28550 题意: 给出一个字符串, 并且给出一个k, 并且保证字符串可...

uva 11552(dp)

题意:有一个整数k和一个字符串,字符串的长度一定是k的倍数,那么可以把字符串分成k组,可以把每组的字符串重组但组的先后顺序不变,连续字母的称为一块,问整个字符串可以形成的最少块是多少。 题解:可以先...

uva 11552

uva 11552    刚开始用的贪心,wawawawawa,心都碎了,改来改去我觉得已经很完美了还是不行。。。后来学长说用dp  真是d了个p的。。。动态规划想不好还真容易看成贪心,可是我现在依...

AC自动机模板 LA4670 Dominating Patterns 出现次数最多的字串 BNUOJ11552 UVA1449

题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=11552 The archaeologists are going to dec...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)