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 ...
随机推荐
- Luogu P4463 [国家集训队] calc
WJMZBMR的题果然放在几年后看来仍然挺神,提出了一种独特的优化DP的方式 首先我们想一个暴力DP,先定下所有数的顺序(比如强制它递增),然后最后乘上\(n!\)种排列方式就是答案了 那么我们容易想 ...
- flask--Django 基本使用
#导入flaskfrom flask import Flask #创建应用 app = Flask(__name__) #创建根路径视图 @app.route('/') def hello_world ...
- gEdit - GTK+ 基础文本编辑器
语法 gedit [--help] [--version] [文件名] [文件名] [文件名] 等等... 描述 gEdit 是一个 X窗口系统下的基础文本编辑器由 GTK+ 写成.它现在支持建立,打 ...
- centos7设置sshd端口,firewall,selinux设置
https://blog.csdn.net/qq_31927797/article/details/81095829 #停止firewallsystemctl stop firewalld.servi ...
- Bootstrap历练实例:响应式导航栏
响应式的导航栏 为了给导航栏添加响应式特性,您要折叠的内容必须包裹在带有 classes .collapse..navbar-collapse 的 <div> 中.折叠起来的导航栏实际上是 ...
- apache 报413
http://www.hostlift.com/apache/modsecurity-request-body-content-length-is-larger-than-the-configured ...
- 使用Xcode连接开源中国
故事背景: 今天加入一个新的项目组,其实也就是包括我在内就两个人,由于对方在开源中国上建的项目我没法使用. 所以由我接手第一个任务:就是在开源中国上搭建git项目组 前提条件:xcode和 Git(h ...
- (57)zabbix Slide shows幻灯片展示
定义好screen之后,我们想了解服务器状况之时,一般会一个个screen点过去,zabbix提供了幻灯片展示方法,可以定义多个Slide,一个slide中可以包含多个screen. 创建slide ...
- 00048_this关键字
1.this调用构造方法 (1)构造方法之间的调用,可以通过this关键字来完成: (2)构造方法调用格式 this(参数列表); (3)小案例 class Person { // Person的成员 ...
- 大数据学习——Storm集群搭建
安装storm之前要安装zookeeper 一.安装storm步骤 1.下载安装包 2.解压安装包 .tar.gz storm 3.修改配置文件 mv /root/apps/storm/conf/st ...