la 4394 string painter 区间dp
2016-03-14 15:26
344 查看
开始练dp了,要好好练啊。
这是一道区间dp的题目,每次对序列的一个区间操作,区间dp有一个特点是,对于某一个区间,如果你没有对这个区间进行操作,而对这个区间的子区间进行操作,那么这个区间就没有必要再操作了,否则对子区间的操作就成了费操作,这个是区间dp的决策,决策是对本区间进行大操作,还是分到其他子区间(o(n))的分法
本题就是这样,dp【i】【j】表示从i到j的原序列变成末序列需要的费用,显然看是否对序列本身操作,然后分到子区间中,这个时候发现对本身进行操作之后,就会变成一个全是同种字母的区间,把他们也加入状态,还是同上的dp,就可以得到答案,不过百度大神有先算白板的,复杂度更低一点
每个字符串,到末状态,如果说修改本身的话,一定是在末状态的头和尾相等的时候修改,否则和分到子区间再分别修改是一样的,这样就又减少了决策时转移的状态数
反正我是A了……好题啊,充分利用了区间dp的性质
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 100;
const int INF = 111111111;
char sa[maxn],sb[maxn];
int d[maxn][maxn][27];
int length;
//一坨到对应的
int dp(int l,int r,int col)//26表示原串
{
int tem;
if (d[l][r][col] != -1) return d[l][r][col];
if (l > r) return 0;//只有0个,相等
if (l == r) {//只有一个
if (col == 26) d[l][r][col] = (1 - (sa[l] == sb[l]));
else d[l][r][col] = (1 - (col == sb[l] - 'a'));
return d[l][r][col];
}
//涂整个
if (sb[l] == sb[r]) tem = dp(l + 1,r - 1,sb[l] - 'a') + 1;
//else tem = min(dp(l + 1,r,sb[l] - 'a'),dp(l , r - 1,sb[r] - 'a')) + 1; 加了这句话会慢几乎一倍,没有深刻分析问题
//分开
for(int i = l + 1; i <= r; i++)
tem = min(tem,dp(l,i - 1,col) + dp(i,r,col));
d[l][r][col] = tem;
return tem;
}
int main()
{
while(scanf("%s %s",sa,sb) != EOF){
length = strlen(sa);
memset(d,-1,sizeof(d));
printf("%d\n",dp(0,length - 1,26));
}
return 0;
}
这是一道区间dp的题目,每次对序列的一个区间操作,区间dp有一个特点是,对于某一个区间,如果你没有对这个区间进行操作,而对这个区间的子区间进行操作,那么这个区间就没有必要再操作了,否则对子区间的操作就成了费操作,这个是区间dp的决策,决策是对本区间进行大操作,还是分到其他子区间(o(n))的分法
本题就是这样,dp【i】【j】表示从i到j的原序列变成末序列需要的费用,显然看是否对序列本身操作,然后分到子区间中,这个时候发现对本身进行操作之后,就会变成一个全是同种字母的区间,把他们也加入状态,还是同上的dp,就可以得到答案,不过百度大神有先算白板的,复杂度更低一点
每个字符串,到末状态,如果说修改本身的话,一定是在末状态的头和尾相等的时候修改,否则和分到子区间再分别修改是一样的,这样就又减少了决策时转移的状态数
反正我是A了……好题啊,充分利用了区间dp的性质
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 100;
const int INF = 111111111;
char sa[maxn],sb[maxn];
int d[maxn][maxn][27];
int length;
//一坨到对应的
int dp(int l,int r,int col)//26表示原串
{
int tem;
if (d[l][r][col] != -1) return d[l][r][col];
if (l > r) return 0;//只有0个,相等
if (l == r) {//只有一个
if (col == 26) d[l][r][col] = (1 - (sa[l] == sb[l]));
else d[l][r][col] = (1 - (col == sb[l] - 'a'));
return d[l][r][col];
}
//涂整个
if (sb[l] == sb[r]) tem = dp(l + 1,r - 1,sb[l] - 'a') + 1;
//else tem = min(dp(l + 1,r,sb[l] - 'a'),dp(l , r - 1,sb[r] - 'a')) + 1; 加了这句话会慢几乎一倍,没有深刻分析问题
//分开
for(int i = l + 1; i <= r; i++)
tem = min(tem,dp(l,i - 1,col) + dp(i,r,col));
d[l][r][col] = tem;
return tem;
}
int main()
{
while(scanf("%s %s",sa,sb) != EOF){
length = strlen(sa);
memset(d,-1,sizeof(d));
printf("%d\n",dp(0,length - 1,26));
}
return 0;
}
相关文章推荐
- STL区间成员函数及区间算法总结
- sql 查询记录数结果集某个区间内记录
- Java获得指定区间数的方法
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 简单的四则运算
- 数的奇偶性
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- 矩阵的乘法操作
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 蚂蚁爬行问题
- 蚂蚁爬行问题