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. ios手势识别代理

    之前做优质派时写了个仿网易新闻导航的第三方,由于当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0 ...

  2. NDK编程jni学习入门,声明native方法,使其作为java与c的交互接口

    首先,新建工程,简历一个jave类,在其中声明native方法,关键字为native,表面这个方法是从java以为的语言实现. 其次,要实用javac编译此java文件(javac是jdk中的命令,需 ...

  3. 初学SpringMVC,使用MVC进行文件上传

    最近在做一个文件上传的功能,走了不少弯路,话不多说,直接上代码: 导入各种jar包,首先是applicationContext.xml配置文件中: <!-- 配置文件解析器 --> < ...

  4. 【13】MD5编码、Zlib压缩解压缩

    1.MD5加密 /// <summary> /// 使用MD5加密算法 /// </summary> /// <param name="md5MessageSt ...

  5. 二:Bootstrap-css组件

    Glyphicons 图标: span.glyphicon glyphicon-align-center 下拉菜单: div.dropdown/div.btn-group button[data-to ...

  6. K:求取数组中最大连续子序列和的四个算法

    相关介绍:  求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...

  7. shutil的一些基本用法

    import shutil import time import tarfile # 将文件内容拷贝到另一个文件中 shutil.copyfileobj(open('a1', 'r'), open(' ...

  8. [COCI2006-2007#1] Bond

    状压DP \(dp[i]\)表示当前选人状态为\(i\)且选择了前\(i.count()\)个物品时最大的概率 #include"cstdio" #include"cst ...

  9. JavaScript自定义字符串格式化

    在JS中没有字符串拼接的方法,如过要使用怎么办呢?这时我们可以通过字符串的prototype可以自定义方法. <script> String.prototype.format = func ...

  10. Django之Form字段插件

    一.Django内置Form组件:        在使用Django内置的Form组件时,里面包含了许多[字段]和[插件],也就是验证用户输入的请求以及生成显示在前端的HTML.下面介绍一下用法: F ...