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 ...
随机推荐
- Codeforces Round #318 (Div. 2) C Bear and Poker (数学)
简单题,求一下所有数的2和3的幂是任意调整的,把2和3的因子除掉以后必须相等. 求lcm,爆了long long.我得好好反省一下,对连乘不敏感 #include<bits/stdc++.h&g ...
- 怎么在webstorm中设置代码模板
大家都知道webstorm对程序员来说是一个很好用的IDE.我们输入几个关键字,webstorm就会给出提示,大大提高了我们的开发效率,可有时候webstorm的默认设置不能满足我们的个性化代码模板的 ...
- Java 的访问权限
public>protected>默认(包访问权限)>private,因为protected除了可以被同一包访问,还可以被包外的子类所访问
- MySQL常用表结构查询语句
在我们使用数据库进行查询或者建表时,经常需要查看表结构,下面以employees数据库中的departments表为例进行表结构查询: departments表:(2列9行) +---------+- ...
- centos下nginx安装和配置
注:此文是根据前辈的博客和自己实际动手总结出来的,不喜勿喷 1.准备工作 Nginx的安装依赖于以下三个包,意思就是在安装Nginx之前首先必须安装一下的三个包,注意安装顺序如下: 1 SSL功能需要 ...
- sql server存储过程修改,存储到mysql笔记
由于有些项目要迁移到mysql上,数据迁移用MySQLWorkbench就能很好的迁移,最难的是存储过程之类的. 下面是sql server存储过程和mysql存储过程的转化: SQL SERVER: ...
- ps命令查看子进程
[root@centos7 log]# ps -f -e -o pid,ppid,pgid,comm PID PPID PGID COMMAND 5070 5068 5070 bash 7169 50 ...
- PWA天气应用
https://codelabs.developers.google.com/codelabs/your-first-pwapp/#0 1.介绍 这里将使用PWA技术来构建一个天气web应用,这个ap ...
- React碰到v-if
最近在重构公司老项目,由于本人以前的技术栈是vue, 换工作后发现现在公司的技术栈是react, 所以重构的过程是及其痛苦.加之项目又是几年前的老项目,不敢大改,比葫芦画瓢比比皆是.本文就介绍下遇到的 ...
- python爬虫基础07-selenium大全1/8-安装和简单使用
Selenium笔记(1)安装和简单使用 本文集链接:https://www.jianshu.com/nb/25338984 简介 Selenium是一个用于Web应用程序测试的工具. Seleniu ...