wap网测一道题目
1. 给定一个字符串s, 1 <= len(s) <= 3000, 定义odd palindrome string为长度为奇数的回文串, 求s中该奇回文串的个数。
比如axbcba , 结果为12.
实在想不出来该怎么做,想到一个笨办法,但是tle。 考察左边a对回文串的贡献, 它依次跟右边的a配对,使得这两个a之间的奇回文串翻倍,然后做记忆化搜索。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
const int mod = 1e9 + ; ll dp[][];
string s;
ll work(int x, int y) {
if(x > y) return ;
if(x == y) return ;
ll& res = dp[x][y];
if(res != ) return res;
res++;
for (int j = y; j > x; j--) {
if(s[j] == s[x]) {
res = (res + work(x + , j - )) % mod;
}
}
res = (res + work(x + , y)) % mod;
return res;
}
void solve() {
for (int i = ; i < ; i++) {
s += (char) ('a' + i % );
}
//cin >> s;
cout << s << endl;
cout << work(, s.size() - ) << endl;
} int main() {
freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
ios::sync_with_stdio();
cin.tie(); cout.tie();
solve();
return ;
}
问了下,同学的方法,解法比较巧妙。对每一个字符,求左右2边的相同子序列的个数。寻找递推方程。
int dp[][];
int solve(string s) {
int n = s.size(), res = ;
memset(dp, , sizeof(dp));
for(int i = ; i <= n; i++){
for(int j = n; j > i; j--){
if(s[i-] == s[j-]){
dp[i][j] = (dp[i-][j] + dp[i][j+] + ) % MOD;
}
else{
dp[i][j] = ((dp[i-][j] + dp[i][j+])%MOD +(- dp[i-][j+]) )%MOD;
}
}
}
for(int i = ; i <= n; i++){
res = ((res + dp[i-][i+])%MOD + ) % MOD;
}
return res;
}
看了这个解法,我就感觉有点在哪里见过的赶脚, 然后想到以前做过的一道题, 数字符串s里面回文子序列的个数。
就是这个题目:https://hihocoder.com/problemset/problem/1149 当时什么都不懂, 现在大概有点想法了。
这个题目的代码如下:
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
const int mod = ;
ll dp[][];
char s[];
void solve() {
scanf("%s", s);
memset(dp, , sizeof dp);
int n = strlen(s);
for (int j = ; j <= n; j++) {
for (int i = ; i <= n; i++) {
int r = i + j - ;
if(j == ) {
dp[i][r] = ;
} else {
if(s[i - ] == s[r - ]) {
dp[i][r] = (dp[i][r - ] + dp[i + ][r] + ) % mod;
} else {
dp[i][r] = ((dp[i][r - ] + dp[i + ][r] - dp[i + ][r - ]) % mod + mod) % mod;
}
}
}
}
printf("%lld\n", dp[][n]);
} int main() {
freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
int _;
scanf("%d", &_);
for (int i = ; i <= _; i++) {
printf("Case #%d: ", i);
solve();
}
return ;
}
然后,我就想着,这道题目能不能这样做呢, 其实也是可以的。
定义dp[i][j],为区间[i. j]奇回文的个数, 显然长度为1的时候为1, 长度为2的时候为2, 然后转移方程就跟上面的hihocode回文子序列的个数差不多了。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
const int mod = 1e9 + ;
string s;
ll dp[][];
void solve() {
for (int i = ; i < ; i++) {
s += (char) ('a' + i % );
}
//cin >> s;
cout << s << endl;
int n = s.size();
for (int i = ; i <= n; i++) {
for (int j = ; j <= n; j++) {
int l = j, r = j + i - ;
if(r > n) continue;
if(i == ) {
dp[l][r] = ;
} else if(i == ){
dp[l][r] = ;
} else {
if(s[l - ] == s[r - ]) {
dp[l][r] = (dp[l + ][r] + dp[l][r - ]) % mod;
} else {
dp[l][r] = (dp[l + ][r] + dp[l][r - ] - dp[l + ][r - ] + mod) % mod;
}
}
//cout << l << " " << r << " " << dp[l][r] << endl;
}
}
cout << dp[][n] << endl;
} int main() {
freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
ios::sync_with_stdio();
cin.tie(); cout.tie();
solve();
return ;
}
以前不是很了解这种dp的套路,现在大概是有点想法了。
wap网测一道题目的更多相关文章
- L1-3 宇宙无敌加法器 - 令人激动的一道题目
L1-3 宇宙无敌加法器 - 令人激动的一道题目 感觉好久没有这么认真的做一道题了,今天看到一句话, 说是编程是一个工程型的工作,想要学好,"无他,唯手熟尔" 之前觉得自己笨,怀疑 ...
- wap 5.23 网测几道题目
1. n个犯人,m个省份, 如果相邻的2个犯人来自同一省份,则是不安全的,求不安全的个数. 正难则反,用全部的个数减去非法的个数,就是最后的答案. m^n - m * (m - 1) ^ (n - 1 ...
- xctf的一道题目(77777)
这次比赛我没有参加,这是结束之后才做的题目 题目链接http://47.97.168.223:23333 根据题目信息,我们要update那个points值,那就是有很大可能这道题目是一个sql注入的 ...
- 巧用string中的contains巧解一道题目
题目:求0—7所能组成的奇数个数.假设最高八位数字. package edu.yuliang.lianxiti50; /* 题目:求0—7所能组成的奇数个数. *程序分析:最少也是1位数,最多能组成8 ...
- 编程使用缓冲流读取试题文件,test6_5.txt 内容如下所示。 每次显示试题文件中的一道题目,读取到字符“*”时暂停读取, 等待用户从键盘输入答案。用户做完全部题目后,程序给出用户的得分。
test6_5.txt内容如下: (1)面向对象程序设计中,把对象的属性和行为组织在同一个模块内的机制叫做( ). A.封装象 B.继承 C.抽象 D.多态 ******************** ...
- 一道题目关于Java类加载
public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println(&q ...
- 对CRC32的小结加上bugku一道题目:好多压缩包
CRC32就是校验值,一般来说不同的文件校验值不一样,所以我们可以挨个爆破,当然这是在文件比较小的时候.下面是几种情形. 1. 我新建了一个flag.txt文档,里面是我的生日20180818 然后我 ...
- Poj 3233 矩阵快速幂,暑假训练专题中的某一道题目,矩阵快速幂的模板
题目链接 请猛戳~ Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 ...
- indeed 4.22 第一次网测
1.第一题 没有看 2. 由于数据范围很小,所以每一层需要全排列,寻找最小的花费,然后所有层加起来就是最后的结果. #include<bits/stdc++.h> #define pb p ...
随机推荐
- 常见的Xshell运行命令
最近接触到了Xshell这个软件,使用这个软件我们来进行连接Linux系统,进去之后我们可能会两眼一抹黑,小编就带大家来学些常见的shell命令. 首先我们要跟大家从最简单的聊起,我们进入Xshell ...
- webpack-dev-middleware 与 webpack-hot-middlware
dev-middleware: live reload的实现: 思考一下我們要如何更新(live reload)呢? 當然是需要取得 webpack 編好的資料啊,於是就需要在從 request 到 ...
- C++入职学习篇--代码规范(持续更新)
C++入职学习篇--代码规范(持续更新) 一.头文件规范 在头文件中大家一般会定义宏.引入库函数.声明.定义全局变量等,在设计时最后进行分类,代码示范(自己瞎琢磨的,请多多指点): #ifndef T ...
- VsCode 格式化插件配置
Beautify 1.在工作目录下建立.jsbeautifyrc文件: { "brace_style": "none,preserve-inline", &qu ...
- 第十四节:pandas之merge()合并
Pandas提供了一个merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口pandas.merge(left,right,how='inner',on=None,left_o ...
- 【模板】RMQ问题 ST表
洛谷3865 #include<cstdio> #include<algorithm> #include<cmath> using namespace std; ; ...
- 【[Offer收割]编程练习赛14 D】剑刃风暴(半径为R的圆能够覆盖的平面上最多点数目模板)
[题目链接]:http://hihocoder.com/problemset/problem/1508 [题意] [题解] 求一个半径为R的圆能够覆盖的平面上的n个点中最多的点数; O(N2log2N ...
- BUPT2017 springtraining(16) #3 ——搜索与动态规划
题目在这里啊 A.最长上升子序列,范围很小所以写了简单的O(n^2)算法 #include <iostream> #define rep(i, j, k) for(int i = j;i ...
- 洛谷—— P1092 虫食算
https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简 ...
- ZooKeeper是什么(转)
ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提 ...