• [1222] English Game

  • 时间限制: 1000 ms 内存限制: 131072 K
  • 问题描写叙述
  • This English game is a simple English words connection game.

    The rules are as follows: there are N English words in a dictionary, and every word has its own weight v. There is a weight if the corresponding
    word is used. Now there is a target string X. You have to pick some words in the dictionary, and then connect them to form X. At the same time, the sum weight of the words you picked must be the biggest.

  • 输入
  • There are several test cases. For each test, N (1<=n<=1000) and X (the length of x is not bigger than 10000) are given at first. Then N rows follow. Each row contains a word wi (the length is not bigger than 30) and the weight of it. Every word is composed
    of lowercases. No two words in the dictionary are the same.
  • 输出
  • For each test case, output the biggest sum weight, if you could not form the string X, output -1.
  • 例子输入
  • 1 aaaa
    a 2
    3 aaa
    a 2
    aa 5
    aaa 6
    4 abc
    a 1
    bc 2
    ab 4
    c 1
    3 abcd
    ab 10
    bc 20
    cd 30
    3 abcd
    cd 100
    abc 1000
    bcd 10000
  • 例子输出
  • 8
    7
    5
    40
    -1

题目大意:

给出一个目标字符串和n个字符串及其相应的权值,求用这些字符串中的1个或多个组成目标字符串的最大权值。

解题思路:

用trie树保存b个字符串及其权值,接下来就是动态规划了。

到达某一点i,遍历trie树找到i+1为第一个字符的字符串。在结束位置j,dp[j]=max(dp[j],dp[i]+val[i+1到j之间的字符串])。除第0位之外,假设dp[i]=0说明没有字符串可以组成0到i之间的字符串,那么就不用查询。

參考代码:

#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int INF=0x3f3f3f3f;
const int MAXN=1e4+50;
typedef long long LL;
struct node
{
node* next[26];
int val;
node()
{
val=0;
memset(next,0,sizeof(next));
}
}*root; int n,L,dp[MAXN];
char s[MAXN]; void trie_insert(node* start,char* word,int v)
{
node* now=start;
int l=strlen(word);
for(int i=0; i<l; i++)
{
int id=word[i]-'a';
if(now->next[id]==NULL)
now->next[id]=new node();
now=now->next[id];
}
now->val=v;
} int trie_query(node* start,int pos)
{
node* now=start;
int i;
for(i=pos+1; i<=L; i++)
{
int id=s[i]-'a';
if(now->next[id]==NULL)
break;
now=now->next[id];
if(now->val)
dp[i]=max(dp[i],dp[pos]+now->val);
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d%s",&n,s+1)!=EOF)
{
root=new node();
L=strlen(s+1);
memset(dp,0,sizeof(dp));
for(int i=0; i<n; i++)
{
char tmp[MAXN];
int d;
scanf("%s%d",tmp,&d);
trie_insert(root,tmp,d);
}
for(int i=0; i<=L; i++)
if(dp[i]||i==0)//假设dp[i]=0说明没有字符串可以组成0到i之间的字符串,那么就不用查询
trie_query(root,i);
printf("%d\n",dp[L]==0?-1:dp[L]);
}
return 0;
}

NBUT 1222 English Game(trie树+DP)的更多相关文章

  1. POJ2004 Mix and build Trie树? dp?

    学习Trie树中,所以上网搜一下Trie树的题,找到这个,人家写着是简单dp,那我就想着能学习到什么Trie树上的dp,但最后发现根本好像跟Trie树没有什么联系嘛... 题意就是给你很多个字符串(长 ...

  2. LA-3942(trie树+dp)

    题意: 给出一个由多个不同单词组成的字典,和一个长字符串,把这个字符串分解成若干个单词的连接,问有多少种方法; 思路: dp[i]表示s[i,L]的方案数,d[i]=∑d[j];s[i,j-1]是一个 ...

  3. Remember the Word,LA3942(Trie树+DP)

    Trie树基础题,记录下代码. #include <cstdio> #include <cstring> #define MaxNode 4005*100 #define No ...

  4. NBUT 1222 English Game 2010辽宁省赛

    Time limit 1000 ms Memory limit 131072 kB This English game is a simple English words connection gam ...

  5. hdu4843(NOI2000) 古城之谜 (trie树+DP)

    Description 著名的考古学家石教授在云梦高原上发现了一处古代城市遗址.让教授欣喜的是在这个他称为冰峰城(Ice-Peak City)的城市中有12块巨大石碑,上面刻着用某种文字书写的资料,他 ...

  6. BZOJ1212[HNOI2004]L语言——trie树+DP

    题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...

  7. Codeforces 615C Running Track(DP + Trie树)

    题目大概说给两个串,问最少要用多少个第一个串的子串(可以翻转)拼成第二个串. UVa1401,一个道理..dp[i]表示前缀i拼接成功所需最少的子串,利用第一个串所有子串建立的Trie树往前枚举转移. ...

  8. UVa1401 Remember the Word(DP+Trie树)

    题目给定一个字符串集合有几种方式拼成一个字符串. dp[i]表示stri...strlen-1的方案数 dp[len]=1 dp[i]=∑dp[j](stri...strj-1∈SET) 用集合的字符 ...

  9. 【10.29校内测试】【线段树】【DP】【二进制Trie树求最小值最大】

    Solution 标程太暴力惹QAQ 相当于是26棵线段树的说QAQ 不过我写了另一种写法,从大到小枚举每一个字母,标记字典序在这个字母之上的位置为1,每次都建一棵线段树,维护1的数量,即区间和. 修 ...

随机推荐

  1. 【Luogu】P2530化工厂装箱员(DP)

    题目链接 不知道做出这道题是我能力的一个提升还是能力的回归. DP.设f[i][j][k][l]是已经取了i个产品,现在手里还拿着j件A,k件B,l件C,最小的操作数. 然后状转方程乱搞啊 #incl ...

  2. 【Luogu】P2831愤怒的小鸟(手算抛物线+状压DP)

    题目链接 设f[s]表示二进制集合表示下的s集合都打掉用了多少小鸟. 预处理出lne[i][j]表示i.j确定的抛物线能打掉的小鸟集合. 于是就有f[s|lne[i][j]]=min(f[s|lne[ ...

  3. SGU 275 To xor or not to xor【最大xor和 高斯消元】

    题目大意:给你n个数(n<=100)要你找出若干个数使他们的异或和最大 思路:高斯-若当消元消完以后削成若干个独立的行向量,将它们异或起来就好 #include<cstdio> #i ...

  4. 算法复习——虚树(消耗战bzoj2286)

    题目: Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战 ...

  5. HashMap构造函数有哪些

    hashMap有4个构造函数: public HashMap(int initialCapacity, float loadFactor) public HashMap(int initialCapa ...

  6. 很好的linux下GPIO驱动详解文章

    原文地址  http://blog.csdn.net/llxmedici/article/details/6282372 打算跟着友善之臂的<mini2440 linux移植开发指南>来做 ...

  7. 有关WebView开发问题(转)

    http://blog.sina.com.cn/s/blog_8241e8510101btvk.html 如何创建WebView: 1.添加权限:AndroidManifest.xml中必须使用许可& ...

  8. Objective C语言中nil、Nil、NULL、NSNull的区别

    以下内容是基于搜集整理的网上资料,供参考. nil:指向Objective C语言中对象的空指针,其定义值为(id)0. Nil:指向Objective C语言中类(Class)的空指针,其定义值为( ...

  9. 在 VirtualBox 5.0 系列中让虚拟机支持 USB 3.0 必须开启 APIC

    VirtualBox 5.0 系列正式支持 USB 3.0,能够在宿主机支持 USB 3.0 的情况下,让虚拟机也选择具备 USB 3.0 的功能.但是经过多方试验,发现必须在 VirtualBox ...

  10. LeetCode OJ--Evaluate Reverse Polish Notation

    http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 栈使用 #include <iostream> #inc ...