codeforces 17C Balance

题意

给定一个串,字符集{'a', 'b', 'c'},操作是:选定相邻的两个字符,把其中一个变成另一个。可以做0次或者多次,问最后可以生成多少种,使得任意一种字符和其他字符的个数相差都不超过1.

题解

一个生成串压缩之后必定都是初始串的子序列,那么只要能枚举所有子序列,其他的很好搞定。

对于枚举的每个子序列,如果它是由初始串最早能生成的产生,那么肯定不会重。

基于这一点,f(i, a, b, c)表示当前由初始串1~i生成子序列,三个字符分别的个数,类似背包转移即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
//--- const int N = 155, P = 51123987; int n, m;
int ne[N][3], f[N][55][55][55];
string s; void add(int &a, int b) {
if((a+=b)>=P) a-=P;
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin >> n >> s;
s = " " + s;
memset(ne, -1, sizeof(ne));
for(int i = sz(s)-1; ~i; --i) {
rep(j, 0, 3) ne[i][j] = ne[i+1][j];
if(i) ne[i][s[i]-'a'] = i;
}
m = (n+2)/3;
f[0][0][0][0] = 1;
rep(i, 0, n+1) {
rep(a, 0, m+1) rep(b, 0, m+1) rep(c, 0, m+1) {
rep(j, 0, 3) if(~ne[i][j]) {
int t = ne[i][j];
add(f[t][a+(j==0)][b+(j==1)][c+(j==2)], f[i][a][b][c]);
}
}
}
int ans = 0, l = n/3, r = m;
rep(i, 1, n+1) {
rep(a, l, r+1) rep(b, l, r+1) rep(c, l, r+1) if(a+b+c==n) {
add(ans, f[i][a][b][c]);
}
}
cout << ans << endl;
return 0;
}

codeforces 17C Balance(动态规划)的更多相关文章

  1. [Codeforces 17C] Balance

    Brief Introduction: 给定一个仅由abc组成的字符串,每个字符可以向左右延展,求最终新的平衡字符串的个数. Algorithm: 关键点在于变换前后字符串中字符的相对位置不会发生改变 ...

  2. Codeforces Flipping game 动态规划基础

    题目链接:http://codeforces.com/problemset/problem/327/A 这道题目有O(N^3)的做法,这里转化为动态规划求解,复杂度是O(N) #include < ...

  3. Codeforces 955F Heaps - 动态规划

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一棵以1为根的树,定义$dp_{k}(u)$表示在$u$的子树内存在的深度最大的满k叉树的深度,求$\sum_{u = 1}^{n}\su ...

  4. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  5. poj 1837 Balance 动态规划 (经典好题,很锻炼思维)

    题目大意:给你一个天平,并给出m个刻度,n个砝码,刻度的绝对值代表距离平衡点的位置,并给出每个砝码的重量.达到平衡状态的方法有几种. 题目思路:首先我们先要明确dp数组的作用,dp[i][j]中,i为 ...

  6. Codeforces 1110D. Jongmah 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1110D.html 题意 给定 n 个数,每一个数都是在 [1,m] 里的整数. 从中取出形如 {x,x,x ...

  7. 近期做的一些DP

    UVa 1625 color length https://blog.csdn.net/Dylan_Frank/article/details/52261424 https://www.cnblogs ...

  8. 【Codeforces自我陶醉水题篇~】(差17C code....)

    Codeforces17A 题意: 有一种素数会等于两个相邻的素数相加 如果在2~n的范围内有至少k个这样的素数,就YES,否则就NO; 思路: 采用直接打表,后面判断一下就好了.那个预处理素数表还是 ...

  9. Codeforces

    Codeforces 7E #include <iostream> #include <cstring> #include <cstdio> #include &l ...

随机推荐

  1. “融而开放、合以创新”T-HIM融合通信技术开发实战

    本文来自腾讯云技术沙龙,本次沙龙主题为T-HIM融合通信技术开发实战 2018年,企业的数字化转型大规模兴起,"数字化经济"时代来临.如何利用数字化技术来支持业务的转型.增长与创新 ...

  2. svn 改英文

  3. Node.js的基础知识(一)

    一.Buffer类 1.创建缓冲区的三种方式 var buffer = new Buffer(10); console.log(buffer); var buffer2 = new Buffer([1 ...

  4. OpenTLD在VS2012和opencv246编译通过

    最近看到了TLD的跟踪视频,觉得很有意思,刚好最近在看行人检测所以就打算下载源码玩一玩,因为源码是Linux版本的(原作者写的是C++和MATLAB的混合编程)C++源码可以在我的博客TLD(一种目标 ...

  5. jQuery全屏滚动插件fullPage.js中文帮助文档API

    jQuery全屏滚动插件fullPage.js中文帮助文档API   发现了一个fullPage.js插件,于是百度了一下,还就是这个插件的作用,其实有很多网站都做了全屏滚动的特效,效果也很好看,今天 ...

  6. [转]WxEmojiView

    本文转自:https://github.com/icindy/WxEmojiView 来源信息 author: Di (微信小程序开发工程师) organization: WeAppDev(微信小程序 ...

  7. MVC-AOP(面向切面编程)思想-Filter 三种注册方式

    在ASP.NET MVC框架中,为我们提供了四种类型的Filter类型包括:IAuthorizationFilter.IActionFilter.IResultFilter.IExceptionFil ...

  8. [Linux]C语言Linux系统编程创建进程

    1.进程ID 每一个进程都由一个唯一的标识符表示,即进程ID,简称pid.系统保证在某时刻每个pid都是唯一的. 1.1分配进程ID 缺省情况下,内核将进程ID的最大值限制为32768,可以在此处设置 ...

  9. oracle lpad rpad函数

    学习并记录 1.情况一 ) from dual; 运行结果如下: email长度5,默认添加3个空格在左边 2.情况二 ) from dual; 运行结果如下: email长度5,截取2两个字符 3. ...

  10. HDU 2955(01背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=2955 这道题求不被抓时的最大金钱.金额是整数,概率是小数.因为数组小标不能是小数,所以我们可以以钱作为weigh ...