http://acm.fzu.edu.cn/problem.php?pid=2158

在密室逃脱游戏中,大家被困在一个密室中,为了逃出密室,需要找到正确的数字密码,于是大家分头行动,分别找到了密码的子序列,而后大家将得到的线索集中整理分析,大家想知道密码最少是多少位。第一行输入一个整数T,表示数据组数。接下来T组数据,对于每组数据,第一行输入一个整数n (1<=n<=7),表示有n个人,接下来第2到n+1行每行输入一串数字,分别表示第i个人得到的密码子序列(长度<=6)。

1
3
123
14
21
5
比赛的时候是3秒,以前在做搜索的遇到过类似的题目,我是用A*过的.....在这里被卡住了
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int len[8],n,flag,p,dp[8][10];
char s[8][8]; int deal()
{
int maxn=0;
for(int i=0;i<n;i++)
maxn=max(maxn,len[i]);
return maxn;
}
int deal1()
{
int sum=0;
for(int j=0;j<=9;j++)
{
int maxn=0;
for(int i=0;i<n;i++)
{
maxn=max(maxn,dp[i][j]);
}
sum+=maxn;
}
return sum;
}
void dfs(int step)
{
if(flag==1)
return;
int x=deal();
int y=deal1();
if(x==0)
{
flag=1;
return;
}
if(step+x>p||step+y>p)
return;
for(int i=0;i<n;i++)
{
if(len[i]==0) continue;
int f[10],cnt=0;
int tmp=len[i]-1;
int xx=s[i][tmp]-'0';
for(int j=0;j<n;j++)
{
if(len[j]==0) continue;
int tmp1=len[j]-1;
if(s[i][tmp]==s[j][tmp1])
{
len[j]--;
f[cnt++]=j;
dp[j][xx]--;
}
}
if(cnt)
{
dfs(step+1);
for(int i=0;i<cnt;i++)
{
int tmp2=f[i];
len[tmp2]++;
dp[tmp2][xx]++;
}
}
}
}
int main()
{
int text;
scanf("%d",&text);
while(text--)
{
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
len[i]=strlen(s[i]);
for(int j=0;j<len[i];j++)
{
int tmp=s[i][j]-'0';
dp[i][tmp]++;
}
}
p=flag=0;
p=max(deal1(),deal());
while(1)
{
dfs(0);
if(flag==1)
break;
p++;
}
printf("%d\n",p);
}
return 0;
}

  比赛完了,挂出来是1s的时候,在朋友的提醒下,用dp过的,简单的说下思路:

我开了7维dp,每一维分别对应这一维的字符串还有多少个字母没有匹配完的情况下所需要的最少字符个数。

我采取的是从n个字符串的最后开始往前面匹配的,每次找一个字符,看它是否与其它几个字符串相应位置上的字符相等,相等就-1,我所采取的方法是记忆化搜索,感觉这样容易把思路提现出来.......下面是代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define inf (1<<28)
int dp[7][7][7][7][7][7][7],n,t[8];
char s[8][10]; int dfs(int a,int b,int c,int d,int e,int f,int g)
{
if(a==0&&b==0&&c==0&&d==0&&e==0&&f==0&&g==0)
return 0;
if(dp[a][b][c][d][e][f][g]) return dp[a][b][c][d][e][f][g];
//int h[7];
/*h[0]=a;
h[1]=b;
h[2]=c;
h[3]=d;
h[4]=e;
h[5]=f;*/
int minx=inf;
//if(a>0)
for(int j=0;j<n;j++)
{
if(t[j]==0) continue;
int f[7],cnt=0;
int tmp=t[j];
for(int i=0;i<n;i++)
{
if(t[i]==0) continue;
int tmp1=t[i];
if(s[i][tmp1-1]==s[j][tmp-1])
{
//if(a==3&&b==2&&c==2)
//printf("%c %c %d %d\n",s[i][t[i]-1],s[j][t[j]-1],i,j);
f[cnt++]=i;
t[i]--;
}
}
//if(a==3&&b==2&&c==2)
//printf("%d %d %d\n",t[0],t[1],t[2]);
//if(t[0]==3&&t[1]==1&&t[2]==1)
//printf("%c\n",s[j][t[j]-1]);
if(cnt)
{
int p=1+dfs(t[0],t[1],t[2],t[3],t[4],t[5],t[6]);
minx=min(minx,p);
//if(a==2&&b==1&&c==2)
//printf("%d %d %d %d %d\n",t[0],t[1],t[2],minx,p-1);
for(int i=0;i<cnt;i++)
{
int x=f[i];
t[x]++;
}
}
}
dp[a][b][c][d][e][f][g]=minx;
//printf("%d %d %d %d\n",a,b,c,minx);
return minx;
}
int main()
{
int text;
scanf("%d",&text);
while(text--)
{
scanf("%d",&n);
memset(dp,0,sizeof(dp));
memset(t,0,sizeof(t));
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
t[i]=strlen(s[i]);
//printf("%d\n",t[i]);
}
printf("%d\n",dfs(t[0],t[1],t[2],t[3],t[4],t[5],t[6]));
//for(int i=0;i<n;i++)
//printf("%d\t",t[i]);
}
return 0;
}

  

 

fzu2158的更多相关文章

随机推荐

  1. unknown log format "main" in /nginx/conf/nginx.conf

    vi /nginx/conf/nginx.conf找到http{ }模块中的 log_format去掉注释,或是log_format写到了别处. 解决方法: 将log_format 写到http开头 ...

  2. 进阶之路(基础篇) - 010 Arduino 函数(基本、串口、SPI)

    一.基本函数 pinMode(引脚号,模式); digitalWrite(引脚号,电平状态);          //默认低电平(或浮空) digitalRead(数字输入端口号); analogRe ...

  3. resume.c

    resume.c //采用CURLOPT_RESUME_FROM_LARGE 实现文件断点续传功能 #include <stdlib.h> #include <stdio.h> ...

  4. 如何创建magento模块z之Hello World例子(转)

    步骤:1.创建一个Hello World模块2.为这个模块配置路由3.为这个模块创建执行控制器 创建Hello World模块 创建模块的结构目录:app/core/local/Sjolzy/Hell ...

  5. 指尖下的js —— 多触式web前端开发之三:处理复杂手势(转)

    这篇文章着重介绍多触式设备上特有的gesture event(android和iOS对这个事件的封装大同小异).这个事件是对touch event的更高层的封装,和touch一样,它同样包括gestu ...

  6. openstack neutron 深入

    一.概述 环境说明:

  7. Android Studio 常见问题汇总

    一.字体大小问题 在android studio的使用过程中没有发现类似于Eclipse中的font选项,调节字体大小方法如下: 1.File---- >Settings,找到Editor 2. ...

  8. 【算法】MD5加密

    1.什么是MD5 MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法),主流编程语言普遍 ...

  9. Android水波纹特效的简单实现

    我的开源页面指示器框架 MagicIndicator,各位一定不要错过哦. 水波纹特效,想必大家或多或少见过,在我的印象中,大致有如下几种: 支付宝 "咻咻咻" 式 流量球 &qu ...

  10. 图床神器:七牛云 + Mpic + FScapture

    概述 最近在搞Markdown的东西,遇到了一个很棘手的问题,即图片的显示:通用的图片,可以直接网上搜索,但有时候需要自己截一些图或者对下载的图片进行修改,在本地存储完全没有问题,但Markdown写 ...