NOJ 1111 保险箱的密码 【大红】 [区间dp]
保险箱的密码 【大红】
总提交 : 118 测试通过 : 3
题目描述
输入
第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括两行:
l 第1行给出密码锁上初始的0、1数字串(不超过200)
l 第2行给出保险箱的正确密码
输出
对于每个测试用例:
l 开启保险箱需要的最少变换数
样例输入
2
000
111
1011
0010
样例输出
1
2
题目来源
“IBM南邮杯”团队赛2009
|
Accepted
|
953MS
|
724K
|
2732Byte
|
2015-02-10 10:20:01.0
|
|||
|
Time Limit Exceed at Test 1
|
2724Byte
|
2015-02-10 10:18:11.0
|
题解:
区间dp
对于 i-j的区间,整个区间置0或置1,至多只会出现一次
因为你如果再置,就会把前面的操作覆盖,没有意义
所以,下面的操作长度,必然都小于 i-j
同时可以证明,重叠的区间操作也是没有意义的,同理:会覆盖前面的某些操作
所以,可以不断把区间缩小
加上记忆化就可以水过了,不过应该还有更加优化的方法,有待思考。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<string> #define N 205
#define M 105
#define mod 10000007
//#define p 10000007
#define mod2 1000000000
#define ll long long
#define LL long long
#define eps 1e-6
#define inf 100000000
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int T;
char s[N];
char t[N];
int dp[N][N];
int dp1[N][N];
int dp0[N][N];
int le;
int ans; int fun(int l,int r);
int fun0(int l,int r);
int fun1(int l,int r); void ini()
{
memset(dp,-,sizeof(dp));
memset(dp1,-,sizeof(dp1));
memset(dp0,-,sizeof(dp0));
scanf("%s",s+);
scanf("%s",t+);
le=strlen(s+);
} int fun1(int l,int r)
{
if(dp1[l][r]!=-) return dp1[l][r];
int re;
int st=l;
int en=r;
for(st=l;st<=r;st++){
if(t[st]=='') break;
}
if(st>r) return dp1[l][r]=;
for(en=r;en>=st;en--){
if(t[en]=='') break;
}
if(st==en){
return dp1[l][r]=;
}
re=fun0(st,en)+;
dp1[l][r]=re;
return re;
} int fun0(int l,int r)
{
if(dp0[l][r]!=-) return dp0[l][r];
int st=l;
int en=r;
int re;
for(st=l;st<=r;st++){
if(t[st]=='') break;
}
if(st>r) return dp0[l][r]=;
for(en=r;en>=st;en--){
if(t[en]=='') break;
}
if(st==en){
return dp0[l][r]=;
}
re=fun1(st,en)+;
dp0[l][r]=re;
return re;
} int fun(int l,int r)
{
if(dp[l][r]!=-) return dp[l][r];
int st=l;
int en=r;
for(st=l;st<=r;st++){
if(s[st]!=t[st]) break;
}
if(st>r) return dp[l][r]=;
for(en=r;en>=st;en--){
if(s[en]!=t[en]) break;
}
if(st==en){
return dp[l][r]=;
}
int i;
int re=;
for(i=st+;i<=en;i++){
re=min(re,fun(st,i-)+fun(i,en));
}
re=min(re,fun1(st,en)+);
re=min(re,fun0(st,en)+);
dp[l][r]=re;
return re;
} void solve()
{
ans=fun(,le);
} void out()
{
/*
int i,j;
for(i=1;i<=le;i++){
for(j=i;j<=le;j++){
printf(" i=%d j=%d dp1=%d dp0=%d dp=%d\n",i,j,dp1[i][j],dp0[i][j],dp[i][j]);
}
}*/
printf("%d\n",ans);
} int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d",&T);
//for(int ccnt=1;ccnt<=T;ccnt++)
while(T--)
//scanf("%d%d",&n,&m);
//while(scanf("%s",s)!=EOF)
{
ini();
solve();
out();
}
return ;
}
继续思考,将区间分成两部分时,原串和正确串已经相同的部分可以跳过,故可以减少好多操作,当成剪枝1
|
Accepted
|
375MS
|
724K
|
2924Byte
|
2015-02-10 10:48:12.0
|
|||
|
Wrong Answer at Test 1
|
2738Byte
|
2015-02-10 10:33:44.0
|
|||||
|
Accepted
|
953MS
|
724K
|
2732Byte
|
2015-02-10 10:20:01.0
|
|||
|
Time Limit Exceed at Test 1
|
2724Byte
|
2015-02-10 10:18:11.0
|
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<string> #define N 205
#define M 105
#define mod 10000007
//#define p 10000007
#define mod2 1000000000
#define ll long long
#define LL long long
#define eps 1e-6
#define inf 100000000
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int T;
char s[N];
char t[N];
int dp[N][N];
int dp1[N][N];
int dp0[N][N];
int le;
int ans; int fun(int l,int r);
int fun0(int l,int r);
int fun1(int l,int r); void ini()
{
memset(dp,-,sizeof(dp));
memset(dp1,-,sizeof(dp1));
memset(dp0,-,sizeof(dp0));
scanf("%s",s+);
scanf("%s",t+);
le=strlen(s+);
} int fun1(int l,int r)
{
if(dp1[l][r]!=-) return dp1[l][r];
int re;
int st=l;
int en=r;
for(st=l;st<=r;st++){
if(t[st]=='') break;
}
if(st>r) return dp1[l][r]=;
for(en=r;en>=st;en--){
if(t[en]=='') break;
}
if(st==en){
return dp1[l][r]=;
}
re=fun0(st,en)+;
dp1[l][r]=re;
return re;
} int fun0(int l,int r)
{
if(dp0[l][r]!=-) return dp0[l][r];
int st=l;
int en=r;
int re;
for(st=l;st<=r;st++){
if(t[st]=='') break;
}
if(st>r) return dp0[l][r]=;
for(en=r;en>=st;en--){
if(t[en]=='') break;
}
if(st==en){
return dp0[l][r]=;
}
re=fun1(st,en)+;
dp0[l][r]=re;
return re;
} int fun(int l,int r)
{
if(dp[l][r]!=-) return dp[l][r];
int st=l;
int en=r;
for(st=l;st<=r;st++){
if(s[st]!=t[st]) break;
}
if(st>r) return dp[l][r]=;
for(en=r;en>=st;en--){
if(s[en]!=t[en]) break;
}
if(st==en){
return dp[l][r]=;
}
int re=;
int en1,st2;
for(en1=st;en1<=en-;en1++){
if(s[en1]==t[en1]) continue;
for(st2=en1+;st2<=en;st2++){
if(s[st2]==t[st2]) continue;
re=min(re,fun(st,en1)+fun(st2,en));
en1=st2-;
break;
}
}
re=min(re,fun1(st,en)+);
re=min(re,fun0(st,en)+);
dp[l][r]=re;
return re;
} void solve()
{
ans=fun(,le);
} void out()
{
/*
int i,j;
for(i=1;i<=le;i++){
for(j=i;j<=le;j++){
printf(" i=%d j=%d dp1=%d dp0=%d dp=%d\n",i,j,dp1[i][j],dp0[i][j],dp[i][j]);
}
}*/
printf("%d\n",ans);
} int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d",&T);
//for(int ccnt=1;ccnt<=T;ccnt++)
while(T--)
//scanf("%d%d",&n,&m);
//while(scanf("%s",s)!=EOF)
{
ini();
solve();
out();
}
return ;
}
NOJ 1111 保险箱的密码 【大红】 [区间dp]的更多相关文章
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- 区间DP的摸索
(poj真的炸了,以下代码可能有误) 按照下面这个做题顺序,对区间DP不再那么迷了 LOJ1422 是 dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j])而不是d ...
- 【专题】区间dp
1.[nyoj737]石子合并 传送门:点击打开链接 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这 ...
- 区间dp实战练习
题解报告:poj 2955 Brackets(括号匹配) Description We give the following inductive definition of a “regular br ...
- 区间DP复习
区间DP复习 (难度排序:(A,B),(F,G,E,D,H,I,K),(C),(J,L)) 这是一个基本全在bzoj上的复习专题 没有什么可以说的,都是一些基本的dp思想 A [BZOJ1996] [ ...
- 【BZOJ-4380】Myjnie 区间DP
4380: [POI2015]Myjnie Time Limit: 40 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 162 Solved: ...
- 【POJ-1390】Blocks 区间DP
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5252 Accepted: 2165 Descriptio ...
- 区间DP LightOJ 1422 Halloween Costumes
http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...
- BZOJ1055: [HAOI2008]玩具取名[区间DP]
1055: [HAOI2008]玩具取名 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1588 Solved: 925[Submit][Statu ...
随机推荐
- Spring中的事务传播行为与隔离级别
事务传播行为 事务传播行为(为了解决业务层方法之间互相调用的事务问题): 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己 ...
- javascript 中设置window.location.href跳转无效问题解决办法
javascript 中设置window.location.href跳转无效问题解决办法 问题情况 JS中设置window.location.href跳转无效 原因是 a标签的href跳转会执行在wi ...
- python:lambda、filter、map、reduce
lambda 为关键字.filter,map,reduce为内置函数. lambda:实现python中单行最小函数. g = lambda x: x * 2 #相当于 def g(x): retur ...
- 【转】数据库SQL的一些总结
http://www.cnblogs.com/yank/category/104903.html
- Codeforces Round #275 (Div. 2)-A. Counterexample
http://codeforces.com/contest/483/problem/A A. Counterexample time limit per test 1 second memory li ...
- verdi知识点
引用:http://blog.csdn.net/naclkcl9/article/details/5425936 1. verdi 加强了active anotation, active trace和 ...
- mysql随机获取数据
SELECT * FROM `table` AS t1 JOIN ( SELECT ROUND( RAND() * ( (SELECT MAX(id) FROM `table`) - (SELECT ...
- Django之学员管理一
Django之学员管理一 建表结构: #班级表class: id title 1 五年一班 2 五年二班 3 五年三班 4 五年四班 #学生表student: id name 班级ID(FK外键) 1 ...
- XPath与lxml类库
有同学说,我正则用的不好,处理HTML文档很累,有没有其他的方法? 有!那就是XPath,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素. 什么是XML ...
- 算法学习记录-图——最小路径之Floyd算法
floyd算法: 解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包. 设为从到的只以集合中的节点为中间节点的最短路径的长度. 若最短路径经过 ...