NC20260. [SCOI2008]劣质编码
描述
输入描述
第一行包含一个整数n,即符号的个数。
以下n行每行为一个长度不超过50的01串(可能为空串),即各符号的 编码。
输出描述
仅一行,包含一个整数,即最短编码的长度。如果无解,输出-1。
示例1
输入:
4 1 1010 01 10101
输出:
5
C++11(clang++ 3.9) 解法, 执行用时: 187ms, 内存消耗: 26660K, 提交时间: 2020-09-23 14:35:01
#include<bits/stdc++.h> #define LL long long #define vi vector<int> using namespace std; int n,id[35][55],totl,dfn; string str[35]; vi s,t;map<vi,int>mp; queue<vi>q; int main(){ scanf("%d",&n); for(int i=1,l;i<=n;i++){ cin>>str[i];l=str[i].size();totl+=l; if(!l){puts("0");return 0;} for(int j=0;j<l;j++)id[i][j]=dfn++; } s.resize(totl);t.resize(totl); for(int i=1;i<=n;i++)s[id[i][0]]=1; mp[s]=0;q.push(s); while(!q.empty()){ vi u=q.front();q.pop();int ns=mp[u]; for(char ch='0';ch<='1';ch++){ for(int i=0;i<totl;i++)t[i]=0; int ed=0; for(int i=1,l;i<=n;i++){ l=str[i].size(); for(int j=0;j<l;j++)if(str[i][j]==ch){ if(j==l-1)ed+=u[id[i][j]];else t[id[i][j+1]]=u[id[i][j]]; } } if(ed>=3){printf("%d\n",ns+1);return 0;} for(int i=1;i<=n;i++)t[id[i][0]]=ed; if(!mp.count(t))mp[t]=ns+1,q.push(t); } } puts("-1"); return 0; }