http://118.190.162.167/p1013.html
题目描述
小英开了一家咖啡厅,和他的基友们做服务员。每个人不能在咖啡厅服务自己,因此如果某个人想来咖啡厅喝咖啡时正好赶上自己值班,就会变得很尴尬了。为此,小英决定和他的基友们轮班,使这种情况不会发生。现在小英已经知道了咖啡厅接下来的客人名单,客人们到达咖啡厅有严格的先后顺序,同一时间只有一位客人需要服务。你帮助小英找到需要换班次数最少的一种排班方法。
数据范围
1 < T <= 10.
对于小数据, 0 < S, C < 1000.
对于大数据, 0 < S, C < 10 0000.
输入描述
第1行,一个整数T,代表共有T组数据。
第2行,一个整数S,代表服务员数量。
接下来的S行是服务员的名字,名字中可能含有空格。
第S+3行,一个整数C,代表客人数量。
接下来的C行是客人的名字,其中可能包括服务员的名字,名字中可能含有空格。
输出描述
对于每组数据,输出一行,包含一个整数,代表最少所需的换班数。
样例输入(精确内容)
12Small EightSmall Five5Small EightBurningZhouSmall Fivezmsj
样例输出(精确内容)
1
提示
样例中最优的排班方式是先由 Small Five 值班直到他想需要服务时再换到Small Eight。
解题思路:首先,对输入的客人数据进行处理,将客人数组中的服务员按顺序摘取出来,其他信息舍去(普通客人不影响排班)。其次以服务员数组为纵坐标,从客人信息中摘取出来的服务员数据为横坐标,生成一张表。
表1 值班顺序
服务生冲突的地方置1,不冲突的置0,此时将该问题转化成了迷宫问题,可用DFS方法来求的结果(答案貌似没有问题,但超时了)。或者可以使用动态规划的方法来做:新生成一个DP数组,DP表对应位置表示换班次数,从表一的第一行为0的位置开始,进行DP数组补全。
针对DP某一位置(i,j),查找对应的表1 的(i,j)位置,当表1对应位置值为1 时,置DP表对应位置为MAX(MAX值自己定义,起标识作用),当表1对应的位置为0 ,此时需要查看DP表的第(i-1,j)位置的值。若值为MAX,则DP表的第(i,j)处值为DP表中第i-1行中的最小值+1(需要从别的列跳过来),若值不为MAX,则DP表的第(i,j)处值为DP表中第(i-1,j)的值(直接继承下来,不需要从别的列跳过来)。最后取DP表最后一行的最小值。
DP 表
代码:
由于代码大小限制,对DP表只用两行进行迭代
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<algorithm>
#define MAX 10000
using namespace std;
int Min(int *p,int len)
{
int num=MAX;
for(int i=0;i<len;i++)
{
if(p[i]<num)num=p[i];
}
return num;
}
int Map[2][100000]; //代码大小限制,只用两行迭代
int main()
{
int num,num_e,num_g;
//freopen("input.txt","r",stdin);
cin>>num;
while(num--)
{
string str;
vector<string>employee;
vector<string>guest;
cin>>num_e;
cin.ignore();
while(num_e--)
{
getline(cin,str);
employee.push_back(str);
}
cin>>num_g;
cin.ignore();
while(num_g--)
{
getline(cin,str);
for(int i=0;i<employee.size();i++)
{
if(str==employee[i])
{
guest.push_back(str);
break;
}
}
}
memset(Map,0,sizeof(Map));
for(int i=0;i<employee.size();i++) //动态规划表初始化
{
if(employee[i]==guest[0])
Map[0][i]=MAX;
}
for(int i=1;i<guest.size();i++)
{
for(int j=0;j<employee.size();j++)
{
if(employee[j]==guest[i])
{
Map[i%2][j]=MAX;
}
else
{
if(Map[(i-1)%2][j]==MAX){Map[i%2][j]=Min(Map[(i-1)%2],employee.size())+1;}
else {Map[i%2][j]=Map[(i-1)%2][j];}
}
}
}
/*for(int i=0;i<hang;i++)
{ for(int j=0;j<employee.size();j++)
cout<<Map[i][j];
cout<<endl;
}*/
cout<<Min(Map[(guest.size()-1)%2],employee.size())<<endl;
}
return 0;
}