East Central North America 2005-2006 —— ACM(ACronym Maker)
East Central North America 2005-2006 —— ACM(ACronym Maker)
题目来源:
题意:
多组数据,告知那些单词可以被忽略,问有多少种获得某缩写的方法
例如:
2
and
of
ACM academy of computer makers
RADAR radio detection and ranging
LAST CASE
ACM 有 从academy 得到 两种a 的方法。所以输出为
ACM can be formed in 2 ways
题解:
DP题一道,dp(当前处理单词)(对应缩写位)=方案数。
令当前处理单词为i(排除忽略单词),对应缩写位j,则dp(i)(j+1)=dp(i-1)(j)+dp(i)(j)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string>
#include <sstream>
#include <set>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn=200;
int dp[maxn],dp2[maxn],cnt,n;
string T,word[maxn];
set<string> s;
char tstr[maxn];
//取单词
void pre(char *s)
{
stringstream ss(s);
ss >> T;
while(ss >> word[cnt++]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("A.in","r",stdin);
//freopen("A-o.out","w",stdout);
#endif
string str;
while(cin >> n && n)
{
cnt=1;
s.clear();
while(n--)
{
cin >>str;
s.insert(str);
}
scanf("\n");
//有多组数据
while(gets(tstr) && strcmp(tstr,"LAST CASE")!=0)
{
memset(dp,0,sizeof(dp));
cnt=1;
pre(tstr);
dp[0]=1;
//大小写转换
for(int i=0;i<T.size();i++)
T[i]+='a'-'A';
for(int i=1;i<cnt-1;i++)
{
if(s.count(word[i])!=0)
continue;
memset(dp2,0,sizeof(dp2));
for(int j=0;word[i][j];j++)
for(int k=T.size()-1;~k;k--)
{
if(word[i][j] == T[k])
dp2[k+1] += dp[k]+dp2[k];
}
copy(dp2,dp2+maxn,dp); //滚动数组处理(省去处理忽略单词对结果的影响)
}
//大小写转换
for(int i=0;i<T.size();i++)
T[i]-='a'-'A';
if(dp[T.size()])
printf("%s can be formed in %d ways\n",T.c_str(),dp[T.size()]);
else
printf("%s is not a valid abbreviation\n",T.c_str());
}
}
return 0;
}