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 ...
随机推荐
- Makefile入门教程
Makefile介绍 make是一个命令工具,它解释Makefile 中的指令(应该说是规则).在Makefile文件中描述了整个工程所有文件的编译顺序.编译规则.Makefile 有自己的书写格式. ...
- Asp.Net Core 进阶(二) —— 集成Log4net
Asp.Net Core 支持适用于各种内置日志记录API,同时也支持其他第三方日志记录.在我们新建项目后,在Program 文件入口调用了CreateDefaultBuilder,该操作默认将添加以 ...
- QT+动手设计一个登陆窗口+布局
登陆窗口的样式如下: 这里面涉及着窗口的UI设计,重点是局部布局和整体布局, 首先在ui窗口上添加一个容器类(Widget),然后将需要添加的控件放置在容器中,进行局部布局(在进行局部布局的时候可以使 ...
- python之list [ 列表 ]
1. 列表是什么? list [ ] 逗号隔开 是一个容器 可以存放任意类型 列表 == 书包 书包里可以放水杯.衣服.袜子.钱包 钱包里可以放钱.身份证件,可以包套包 2. 列表能干什么? 存储大量 ...
- java上传、下载、删除ftp文件
一共三个类,一个工具类Ftputil.,一个实体类Kmconfig.一个测试类Test 下载地址:http://download.csdn.net/detail/myfmyfmyfmyf/669710 ...
- 基于IMD的包过滤防火墙原理与实现
一.前言二.IMD中间层技术介绍三.passthru例程分析四.部分演示代码五.驱动编译与安装六. 总结 一.前言 前段时间,在安全焦点上看到了TOo2y朋友写的<基于SPI的数据报过滤原理与实 ...
- docker资源汇总
https://github.com/hangyan/docker-resources/blob/master/README_zh.md https://github.com/lightning- ...
- Linux安全调优1:CentOS防火墙的设置与优化
CentOS防火墙的设置与优化 时间:2014-09-11 02:11来源:blog.csdn.net 作者:成长的小虫 的BLOG 举报 点击:4908次 一.设置主机防火墙. 开放: 服务器的:w ...
- DocDokuPLM 2.5安装
安装记录:(大部分是环境安装和配置) 未完待续.
- modprode
modprobe命令 1.modprobe 命令是根据depmod -a的输出/lib/modules/version/modules.dep来加载全部的所需要模块. 2.删除模块的命令是:modpr ...