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

#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的更多相关文章
随机推荐
- 工作8年对技术学习过程的一些 总结 与 感悟 为什么有时迷茫、无奈 学习编程语言的最高境界最重要的是编程思想 T 字发展 学技术忌讳”什么都会“ 每天进步一点等式图 时间管理矩阵
工作这些年对技术学习过程的一些 总结 与 感悟(一) 引言 工作了8年,一路走来总有些感触时不时的浮现在脑海中.写下来留个痕迹,也顺便给大家一点参考.希望能给初学者一点帮助. 入门 进入计算机行业,起 ...
- 进阶之路(基础篇) - 021 arduino基础知识
什么是arduino(翻译自arduino官方介绍)Arduino 是一款便捷灵活.方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE).她适用于艺术家. ...
- resume.c
resume.c //采用CURLOPT_RESUME_FROM_LARGE 实现文件断点续传功能 #include <stdlib.h> #include <stdio.h> ...
- 【javascript】javascript常用函数大全
javascript函数一共可分为五类: •常规函数 •数组函数 •日期函数 •数学函数 •字符串函数 1.常规函数 javascript常规函数包括以下9个函数: ( ...
- MySQL慢查询mysqlsla
转:http://www.osyunwei.com/archives/7659.html 必须在MySQL服务器上安装mysqlsla 1.mysqlsla是perl编写的脚本,运行mysqlsla需 ...
- MongoDB----逻辑与物理存储结构
基本的操作 一.常用的命令和基础知识 1.进入MongoDB shell 首先我们进入到MongoDB所在目录执行 cd /work/app/mongodb/bin/ #启动 ./mongo 为了方便 ...
- ldd命令
ldd命令用于判断某个可执行的 binary 档案含有什么动态函式库. 参数说明: --version 打印ldd的版本号 -v --verbose 打印所有信息,例如包括符号的版本信息 -d --d ...
- [转]什么是C++虚函数、虚函数的作用和使用方法
我们知道,在同一类中是不能定义两个名字相同.参数个数和类型都相同的函数的,否则就是“重复定义”.但是在类的继承层次结构中,在不同的层次中可以出现名字相同.参数个数和类型都相同而功能不同的函数.例如在例 ...
- cent os 6.5 配置vsftpd
1. 下载vsftpd: #yum –y install vsftpd 2. 关闭iptables 查看防火墙状态:/etc/init.d/iptables status 关闭:service ipt ...
- Vue(三):vuex是什么
vuex官网介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue ...