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 ...
随机推荐
- w3 parse a url
最新链接:https://www.w3.org/TR/html53/ 2.6 URLs — HTML5 li, dd li { margin: 1em 0; } dt, dfn { font-wei ...
- bootstrap table 保留翻页选中数据
$(function () { $('#exampleTable').on('uncheck.bs.table check.bs.table check-all.bs.table uncheck-al ...
- javaEE(12)_数据库连接池
一.直接获取数据库连接和通过池获取示意图: 二.编写数据库连接池 1.实现DataSource接口,并实现连接池功能的步骤: •在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加 ...
- 接口和类方法中的 SELF
接口和类方法中的 SELF 由 王巍 (@ONEVCAT) 发布于 2015/06/10 我们在看一些接口的定义时,可能会注意到出现了首字母大写的 Self 出现在类型的位置上: protocol I ...
- c++ 结构体,设置物品体积并输出物品属性
#include <iostream> using namespace std; struct box { char maker[40]; float height; float widt ...
- C++系统学习之六:函数
1.函数基础 典型的函数定义包括:返回类型.函数名.由0个或多个形参组成的列表以及函数体. 2.参数传递 形参初始化的机理和变量初始化一样. 有两种方式:引用传递和值传递 2.1 传值参数 当形参是非 ...
- 【Git版本控制】Git使用教程
1.Git的综述 SVN是集中式版本控制系统,版本库集中放在中央服务器上,而干活时用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器.集 ...
- (21)zabbix创建触发器trigger
1. 创建触发器 了解了什么触发器,接下来看下zabbix触发器怎么创建和配置,方法很简单,请大家往下读,有什么问题请留言. 创建触发器步骤: 点击Configuration(配置) → Hosts( ...
- 解决zend studio代码无法自动提示的3个方法
最近电脑重装,索性把用了好多年的老版本7.x 升级了,网上下载了一个12.x的破解版. 起初一切正常,等导入项目开始开发的时候发现PHP函数尽然没有提示,一脸懵逼! 经过多方查阅和尝试,现在分享3个解 ...
- Mysql 随机函数 rand()
rand() 函数主要有两个用处: 1.是产生随机数, 2.是随机排序(在数据较大的时候会变成性能杀手) 实例: 1.产生一个随机数,默认0~1之间的浮点数 SELECT RAND( ) 2.参数指定 ...