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网测一道题目的更多相关文章

  1. L1-3 宇宙无敌加法器 - 令人激动的一道题目

    L1-3 宇宙无敌加法器 - 令人激动的一道题目 感觉好久没有这么认真的做一道题了,今天看到一句话, 说是编程是一个工程型的工作,想要学好,"无他,唯手熟尔" 之前觉得自己笨,怀疑 ...

  2. wap 5.23 网测几道题目

    1. n个犯人,m个省份, 如果相邻的2个犯人来自同一省份,则是不安全的,求不安全的个数. 正难则反,用全部的个数减去非法的个数,就是最后的答案. m^n - m * (m - 1) ^ (n - 1 ...

  3. xctf的一道题目(77777)

    这次比赛我没有参加,这是结束之后才做的题目 题目链接http://47.97.168.223:23333 根据题目信息,我们要update那个points值,那就是有很大可能这道题目是一个sql注入的 ...

  4. 巧用string中的contains巧解一道题目

    题目:求0—7所能组成的奇数个数.假设最高八位数字. package edu.yuliang.lianxiti50; /* 题目:求0—7所能组成的奇数个数. *程序分析:最少也是1位数,最多能组成8 ...

  5. 编程使用缓冲流读取试题文件,test6_5.txt 内容如下所示。 每次显示试题文件中的一道题目,读取到字符“*”时暂停读取, 等待用户从键盘输入答案。用户做完全部题目后,程序给出用户的得分。

    test6_5.txt内容如下: (1)面向对象程序设计中,把对象的属性和行为组织在同一个模块内的机制叫做( ). A.封装象 B.继承 C.抽象 D.多态 ******************** ...

  6. 一道题目关于Java类加载

    public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println(&q ...

  7. 对CRC32的小结加上bugku一道题目:好多压缩包

    CRC32就是校验值,一般来说不同的文件校验值不一样,所以我们可以挨个爆破,当然这是在文件比较小的时候.下面是几种情形. 1. 我新建了一个flag.txt文档,里面是我的生日20180818 然后我 ...

  8. Poj 3233 矩阵快速幂,暑假训练专题中的某一道题目,矩阵快速幂的模板

    题目链接  请猛戳~ Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 ...

  9. indeed 4.22 第一次网测

    1.第一题 没有看 2. 由于数据范围很小,所以每一层需要全排列,寻找最小的花费,然后所有层加起来就是最后的结果. #include<bits/stdc++.h> #define pb p ...

随机推荐

  1. ajax post 请求报错Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' heade

    jquery ajax跨域请求,webapi webconfig配置 前台代码(放了一部分) function CheckIn(roomno) { $.ajax({ url: 'https://www ...

  2. 1、DataGridView

    DataGridView赋值后 通过RowPostPaint事件绘制行号 private void AddXh() { DataGridViewTextBoxColumn col = new Data ...

  3. c++ map迭代器

    #include <stdio.h> #include <map> using namespace std; int main(){ map<int, int> m ...

  4. C解析config

    #cat bb.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include < ...

  5. 20180429NOIP提高组精英班Day1测试

  6. 网络:NAT使用场景

    NAT:Network Address Translation  网络地址转换 使用场景:家庭局域网,公司局域网的网络设备没有公网IP地址如何访问互联网? 简单图示: 理解一些原理: 1,互联网中网络 ...

  7. python 简单爬取今日头条热点新闻(一)

    今日头条如今在自媒体领域算是比较强大的存在,今天就带大家利用python爬去今日头条的热点新闻,理论上是可以做到无限爬取的: 在浏览器中打开今日头条的链接,选中左侧的热点,在浏览器开发者模式netwo ...

  8. [繁华模拟赛]Evensgn 剪树枝

    Evensgn 剪树枝 题目 繁华中学有一棵苹果树.苹果树有 n 个节点(也就是苹果),n − 1 条边(也就 是树枝).调皮的 Evensgn 爬到苹果树上.他发现这棵苹果树上的苹果有两种:一 种是 ...

  9. sprintf_s函数用法

    函数功能:将数据格式化输出到字符串 函数原型: int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argu ...

  10. node.js 如何完美的从命令行接收参数所传递进来的值

    https://segmentfault.com/q/1010000000367285