codeforces 17C Balance(动态规划)
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(动态规划)的更多相关文章
- [Codeforces 17C] Balance
Brief Introduction: 给定一个仅由abc组成的字符串,每个字符可以向左右延展,求最终新的平衡字符串的个数. Algorithm: 关键点在于变换前后字符串中字符的相对位置不会发生改变 ...
- Codeforces Flipping game 动态规划基础
题目链接:http://codeforces.com/problemset/problem/327/A 这道题目有O(N^3)的做法,这里转化为动态规划求解,复杂度是O(N) #include < ...
- Codeforces 955F Heaps - 动态规划
题目传送门 传送点I 传送点II 传送点III 题目大意 给定一棵以1为根的树,定义$dp_{k}(u)$表示在$u$的子树内存在的深度最大的满k叉树的深度,求$\sum_{u = 1}^{n}\su ...
- Codeforces Gym 101623A - 动态规划
题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...
- poj 1837 Balance 动态规划 (经典好题,很锻炼思维)
题目大意:给你一个天平,并给出m个刻度,n个砝码,刻度的绝对值代表距离平衡点的位置,并给出每个砝码的重量.达到平衡状态的方法有几种. 题目思路:首先我们先要明确dp数组的作用,dp[i][j]中,i为 ...
- Codeforces 1110D. Jongmah 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1110D.html 题意 给定 n 个数,每一个数都是在 [1,m] 里的整数. 从中取出形如 {x,x,x ...
- 近期做的一些DP
UVa 1625 color length https://blog.csdn.net/Dylan_Frank/article/details/52261424 https://www.cnblogs ...
- 【Codeforces自我陶醉水题篇~】(差17C code....)
Codeforces17A 题意: 有一种素数会等于两个相邻的素数相加 如果在2~n的范围内有至少k个这样的素数,就YES,否则就NO; 思路: 采用直接打表,后面判断一下就好了.那个预处理素数表还是 ...
- Codeforces
Codeforces 7E #include <iostream> #include <cstring> #include <cstdio> #include &l ...
随机推荐
- background-position 详解
一.语法 语法:background-position:x, y; 定义:背景图片相对容器原点的起始位置: 取值: 关键字:top | center | bottom | left | cen ...
- CSS3 图标神器 => content:"我是特殊符号"
基本形状 ▲ 9650 25B2 ► 9658 25BA ► 9658 25BA ▼ 9660 25BC ◄ 9668 25C4 ❤ 10084 2764 ✈ 9992 2708 ★ 9733 260 ...
- 从java到web前端再到php,一路走来的小总结
java的学习: 初学者对Java的学习,上来的感觉都是比较难,感觉java的东西很多,如此多的类和接口.有时还弄不懂为啥实例化出一个int空数组为什么数组中默认都是0,实例化一个空字符串数组时(St ...
- 禁止选中页面内容-兼容ie、firefox、chrome
使用js禁止用户选中网页上的内容,IE及Chrome下的方法一样.使用onselectstart, 比如: 在body中加入<body onselectstart="return fa ...
- golang广度优先算法-走迷宫
广度优先遍历,走迷宫思路: 1.创建二维数组,0表示是路,1表示是墙:创建队列Q,存储可遍历的点,Q的第一个元素为起始点 2.从队列中取一个点,开始,按上.左.下.右的顺序遍历周围的点next,nex ...
- jQuery的三种$()方式
http://www.jb51.net/article/21660.htm $号是jQuery“类”的一个别称,$()构造了一个jQuery对象.所以,“$()”可以叫做jQuery的构造函数(个 ...
- [javaSE] 数据结构(AVL树基本概念)
AVL树是高度平衡的二叉树,任何节点的两个子树的高度差别<=1 实现AVL树 定义一个AVL树,AVLTree,定义AVLTree的节点内部类AVLNode,节点包含以下特性: 1.key——关 ...
- centos文件/文件夹操作-检查磁盘、内存、cpu使用情况-vi操作命令
Part1:CentOS文件/文件夹操作 1.新建文件夹 即创建目录 mkdir 文件名 新建一个名为test的文件夹在home下 vi source1 mkdir /home/test 注意:当创建 ...
- 撩课-Python-每天5道面试题-第1天
一. 尽可能详细的描述出一个应用软件, 比如QQ, 在计算机中运行时涉及的软硬件, 以及说明我们编程的侧重点? 电脑开机, 从硬盘中(外部存储设备)加载操作系统(系统软件)到内存(内部存储设备), 并 ...
- springboot之内嵌tomcat修改端口号
第一种: 在配置文件中直接修改 server.port=8089 第二种: 直接定义 TomcatEmbeddedServletContainerFactory,注册bean: @Configurat ...