USACO4.3 Letter Game【枚举·细节】
题意
这道题的题目描述让我好一阵蒙,简述一下题意吧:
给定一些字母的价值(如图所示),给出一个字符串(长度在$3$到$7$之间,可以出现重复的字母)和一个单词库。定义一个单词的价值就是它的字母的价值之和,一组单词的价值就是所有单词的价值之和,一组单词中的单词数量$>=1$,一组单词中的单词可以重复。要求用字符串中的字母拼成单词库中的一组单词,字符串中的字母不可以重复使用(如果字符串中有多个相同的字母,那么这个字母只能用出现的那么多次),求能够得到的单词组的最大价值并输出所有方案(按字典序)
分析
发现字符串的长度在$3$到$7$之间,单词的长度也在长度在$3$到$7$之间,说明一组单词最多有$2$个。
给出的词库大小是$40000$,但是字符串的只在$3$到$7$之间,也就是最多只有$7$种字母,所以有大量的单词实际上是不合法的,我们可以在输入的时候把它们去掉,只保存有用的单词。
更新一组里面只有一个单词的答案,然后两两枚举单词(一组),更新答案。
利用题目给出的单词库本身按字典序排的性质,有序地遍历就可以保证顺序(良心题目)
/*
ID: Starry21
LANG: C++
TASK: lgame
*/
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int v[]={,,,,,,,,,,,,,,,,,,,,,,,,,};
char s[];
int cnt[],c1[][],c2[];
char dic[][];
int len[],val[];
int n;
int ans[][];
int num,maxx=;
void get(int i,int j)
{
int res=val[i]+val[j];
if(res<maxx) return ;
if(res>maxx)
{
maxx=res;
num=;//找到了更大的答案 重新来过
//ans[++num][0]=i,ans[num][1]=j;会在下面一个if里再算一次答案
}
if(res==maxx)
ans[++num][]=i,ans[num][]=j;
return ;
}
int main()
{
//freopen("lgame.in","r",stdin);
scanf("%s",s+);
for(int i=;i<=strlen(s+);i++)
cnt[s[i]-'a']++;
//freopen("lgame.dict","r",stdin);
//freopen("lgame.out","w",stdout);
while(scanf("%s",s+)!=EOF)
{
if(s[]=='.') break;
n++;
memcpy(c1[n],cnt,sizeof(cnt));
int tmp=;
bool f=;
for(int i=;i<=strlen(s+);i++)
{
c1[n][s[i]-'a']--;
if(c1[n][s[i]-'a']<)
{
f=;
n--;
break;
}
tmp+=v[s[i]-'a'];
}
if(f) continue;
strcpy(dic[n]+,s+);
//puts(dic[n]+1);
val[n]=tmp;
len[n]=strlen(s+); }//printf("%d\n",n);
for(int i=;i<=n;i++)
{
//puts(dic[i]+1);
get(i,);
for(int j=i+;j<=n;j++)//字典序 1~i-1 get(j,i)不能保证第一个小
{
bool f=;
memcpy(c2,c1[i],sizeof(c1[i]));
for(int k=;k<=len[j];k++)
{
c2[dic[j][k]-'a']--;
if(c2[dic[j][k]-'a']<)
{
f=;
break;
}
}
if(f) continue;
get(i,j);//字典序
}
}
printf("%d\n",maxx);
for(int i=;i<=num;i++)
{
printf("%s",dic[ans[i][]]+);
if(ans[i][]) printf(" %s",dic[ans[i][]]+);
puts("");
}
return ;
}
/*
prmgroa
profile
program
prom
rag
ram
rom
.
*/
Code
USACO4.3 Letter Game【枚举·细节】的更多相关文章
- java枚举细节
1.在没有枚举之前,我们如果需要一些常量,比如说,我们想用一些常量来代替订单的几种状态,如已下单未付款.已付款未发货.已发货未确认收货.已收货未评价.已评价.我们会定义一个用来装常量的类,比如: p ...
- C#简单的枚举及结构
using System; namespace program { enum WeekDays { a, b, c = ,//11 赋值以后就变成11,不赋值就是2 d, e, f, g }//不能输 ...
- 洛谷 P1119 灾后重建(Floyd)
嗯... 题目链接:https://www.luogu.org/problem/P1119 这道题是一个Floyd的很好的题目,在Floyd的基础上加一点优化: 中转点k在这里不能暴力枚举,否则会超时 ...
- [bzoj1924]P2403 [SDOI2010]所驼门王的宝藏
tarjan+DAG 上的 dp 难点在于建图和连边,其实也不难,就是细节挺恶心 我和正解对拍拍出来 3 个错误... 传送门:luogu bzoj 题目描述 有座宫殿呈矩阵状,由 \(R\times ...
- 【转】结构struct 联合Union和枚举Enum的细节讨论
结构struct 联合Union和枚举Enum的细节讨论 联合(Union)是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换 ...
- Codeforces Round #116 (Div. 2, ACM-ICPC Rules) Letter(DP 枚举)
Letter time limit per test 1 second memory limit per test 256 megabytes input standard input output ...
- Java语法细节 - 内存和枚举
目录 Java申请DirectBuffer ByteBuffer的position,limit,capacity,flip操作之间的关系 枚举实现单例模式 Java申请DirectBuffer /*- ...
- 结构struct 联合Union和枚举Enum的细节讨论
联合(Union)是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换.联合体对象在同一时间只能存储一个成员的值.联合的内存大小 ...
- 【C/C++】C和C++11之enum枚举的使用细节
作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14101271.html 目录 一.前言 二.C中的枚举(enum) 2.1 C中枚举的大小 2.2 C中枚举的取 ...
随机推荐
- poj1015 Jury Compromise[背包]
每一件物品有两个属性.朴素思想是把这两种属性都设计到状态里,但空间爆炸.又因为这两个属性相互间存在制约关系(差的绝对值最小),不妨把答案设计入状态中,设$f[i][j]$选$i$个人,两者之差$j$. ...
- 生成json格式
html页面 <input type="button" value="重新生成JSON" class="button1" id=&qu ...
- GridControl的列DisplayFormat自定义方法
定义格式化的类: public class EnableFormat : IFormatProvider, ICustomFormatter { public object GetFormat(Typ ...
- jmeter测试报告添加报告生成日期时间
<!-- Defined parameters (overrideable) --><xsl:param name="showData" select=" ...
- Linux设置程序开机自启动,系统命令chkconfig及linux /etc/rc.d/目录的详解
整理了linux下程序开启几种方式,转载相关博客做统一记录 <linux程序设置开机自启动>转载自:https://www.cnblogs.com/flcz/p/7691532.html ...
- 一次linux站点安装经验
之前了解了一点,刚过完年回来,顺便研究了一下小程序. http://s.w7.cc/index.php?c=wiki&do=view&id=1&list=84 先申请了一个li ...
- System limit for number of file watchers reached
https://blog.csdn.net/weixin_43760383/article/details/84326032 sudo xed /etc/sysctl.conf 在最下添加 fs.in ...
- 6.集成算法boosting----AdaBoost算法
1.提升算法 提升算法实为将一系列单一算法(如决策树,SVM等)单一算法组合在一起使得模型的准确率更高.这里先介绍两种Bagging(代表算法随机森林),Boosting(代表算法AdaBoost-即 ...
- Android_(传感器)获取手机中的传感器
传感器是一种检测装置,能够感受被测量的信息,并能将检测和感受到的信息按一定规律变换成电信号或其它所需形式的信息输出 Android操作系统中内置了很多的传感器(物理装置),能够探测.感受外界的信号.物 ...
- Java并发编程的艺术笔记(九)——FutureTask详解
FutureTask是一种可以取消的异步的计算任务.它的计算是通过Callable实现的,多用于耗时的计算. 一.FutureTask的三种状态 二.get()和cancel()执行示意 三.使用 一 ...