Codeforces Round #390 (Div. 2) C. Vladik and chat (DP/记忆化搜索)
来源:互联网 发布:2017流行语言网络语言 编辑:程序博客网 时间:2024/06/11 08:55
题意
有n个人和m句话,有些话的说话人不明,要求是每个人不能连着说两句话,每句话不能提到自己,看看能不能将这些话的说话人都找出来,答案可能不固定。
思路
题目的限制只有两个,因此对于每一句说话人不明的话,可以直接枚举可能的说话人,但是暴力搜索复杂度太高,因此可以使用动态规划或者记忆化搜索来求解。因为一个人不能连着说两句话,所以当前枚举的说话人会影响到后面的结果,由于题目只要求任意可行解,我们要做的就是找出一条可行路径
定义par[i][j]=k表示到第i句话为止都可行,并且第i句话是第j个人说的,前面一句话是第k个人说的
代码
#include <bits/stdc++.h>#define mem(a,b) memset(a,b,sizeof(a))#define rep(i,a,b) for(int i=a;i<b;i++)#define debug(a) printf("a =: %d\n",a);const int INF=0x3f3f3f3f;const int maxn=3e5+50;const int Mod=1000000007;const double PI=acos(-1);typedef long long ll;typedef unsigned int ui;using namespace std;bool ok[233][233];int par[233][233];string msgs[233];string ans[233];string users[233];map<string,int> ma;int m,n;bool getAns(){ int pos=m-1; for(int i=0;i<n;i++){ if(par[pos][i]!=-1){ int cur=i; while(pos>=0){ ans[pos]=users[cur]; cur=par[pos][cur]; pos--; } return true; } } return false;}vector<string> split(string &s){ vector<string> ret; string token=""; for(char c:s){ if(isalpha(c) || isdigit(c)) token+=c; else { if(!token.empty()) ret.push_back(token); token=""; } } if(!token.empty()) ret.push_back(token); return ret;}int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);#endif int T; scanf("%d",&T); while(T--){ ma.clear(); scanf("%d",&n); string s; for(int i=0;i<n;i++) { cin>>s; users[i]=s; ma[s]=i; } scanf("%d",&m); getchar(); mem(ok,0); for(int i=0;i<m;i++){ getline(cin,s); int pos=s.find(':'); msgs[i]=s.substr(pos); ans[i]=s.substr(0,pos); if(ans[i]=="?"){ vector<string> sp=split(msgs[i]); for(int j=0;j<n;j++) ok[i][j]=true; for(string ss:sp){ if(ma.find(ss)!=ma.end()) ok[i][ma[ss]]=false; } }else{ ok[i][ma[ans[i]]]=true; } } mem(par,-1); for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(ok[i][j]){ if(i==0) par[i][j]=-2; else{ for(int k=0;k<n;k++){ if(k!=j && par[i-1][k]!=-1){ par[i][j]=k; break; } } } } } } if(getAns()){ for(int i=0;i<m;i++){ printf("%s%s\n",ans[i].c_str(),msgs[i].c_str()); } }else puts("Impossible"); } return 0;}
0 0
- Codeforces Round #390 (Div. 2) C. Vladik and chat (DP/记忆化搜索)
- Codeforces Round #390 (Div. 2)C Vladik and chat
- Codeforces Round #220 (Div. 2)C题:Inna and Dima(记忆化搜索+DP)
- Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip(dp)
- Codeforces Round #220 (Div. 2) C. Inna and Dima (记忆化搜索)
- Codeforces Round #247 (Div. 2)(C)记忆化搜索
- Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip(dp)
- Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip 【线性DP】
- Codeforces Round #384(Div. 2)C. Vladik and fractions【数学】
- Codeforces Round #384 (Div. 2) C Vladik and fractions
- Codeforces Round #384 (Div. 2)-C. Vladik and fractions
- Codeforces Round #384 (Div. 2) C. Vladik and fractions
- Codeforces Round #416 (Div. 2)C. Vladik and Memorable Trip
- Codeforces Round #416 (Div. 2)-C. Vladik and Memorable Trip
- Codeforces Round #416 (Div. 2) C Vladik and Memorable Trip
- Codeforces Round #384 (Div. 2) 743C Vladik and fractions
- Codeforces Round #384 (Div. 2) C. Vladik and fractions
- Codeforces Round #390 (Div. 2)(A,B,C(记忆化搜索),D(贪心,优先队列))
- 微信支付SDKDEMO运行编译报错
- 算法之路二:刘汝佳算法竞赛入门经典:c++模板
- [bzoj3721]Final Bazarek
- 设备驱动中的并发控制 (2)
- Ubuntu14.04 ROS Indigo安装教程,以及卸载方法
- Codeforces Round #390 (Div. 2) C. Vladik and chat (DP/记忆化搜索)
- 257. Binary Tree Paths
- CentOS6 配置FTP服务器
- 一份 c++的DoxyGen 的注释模板
- 72. Edit Distance
- 最容易理解的对卷积(convolution)的解释
- Selenium参数化-使用eclipse Arguments
- 搜索旋转排序数组
- LeetCode 111. minimum depth of binary tree