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 ...
随机推荐
- CAD绘制一个角度标注(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawDimAngular 绘制一个角度标注.详细说明如下: 参数 说明 DOUBLE dAngleVertexX 角度标注的顶点的X值 DOUBLE dA ...
- Error from server at http://127.0.0.1:8983/solr/xxx: undefined field type
undefined field type就是说没有定义type类型,这样情况下,可以新建一个带type的索引,比如:{type:1, id:1, name:"张三"}
- golang实现高阶函数之map
package main import "fmt" func iMap(num []int, f func(a int) int) []int{ var r []int for _ ...
- Python - 面对对象(基础)
目录 Python - 面对对象(基础) 一. 概述 二. 创建类和对象 三. 面向对象三大特征 封装 继承 多态 Python - 面对对象(基础) 一. 概述 面向过程:根据业务逻辑从上到下写垒代 ...
- DSP28035的编程初步--GPIO操作
明白DSP编程的基本流程,熟悉DSP28035的GPIO的使用.代码执行流程:首先是系统时钟的选择.其次是PIE中断向量表的初始化.一些外设的初始化操作While(){}根据EXPERIMENTER’ ...
- BZOJ 1603 USACO 2008 Oct. 打谷机
[题解] 水题.. 保存连接方式,按顺序处理即可. #include<cstdio> #include<algorithm> using namespace std; int ...
- 【[Offer收割]编程练习赛14 C】可疑的记录
[题目链接]:http://hihocoder.com/problemset/problem/1507 [题意] [题解] 如果多出来一个的话; 某个人的父亲节点就会变成两个 找到有两个父亲节点的人就 ...
- RaspberryPi3安装CentOS7教程
1.准备 Centos 7 AMR版镜像下载地址: http://mirror.centos.org/altarch/7/isos/armhfp/ 下载得到:CentOS-Userland-7-arm ...
- hdu 2527哈夫曼树(二叉树的运用)
#include<stdio.h> #include<string.h> #define N 100 #define INF 2000000000 int b[N]; c ...
- python编码小记
Python编码小记 标签(空格分隔): 编程 python 1.list类型remove()操作 列表对象执行remove()函数后,会自动退出循环,所以如果想利用一个单独的for循环删除列表中多个 ...