HNU 13108 Just Another Knapsack Problem DP + Trie树优化
题意:
给你一个文本串,和一些模式串,每个模式串都有一个价值,让你选一些模式串来组成文本串,使获得的价值最大。每个模式串不止能用一次。
思路:
多重背包,枚举文本串的每个位置和模式串,把该模式串拼接在当前位置,看下一个位置是否能得到更优值。但是,存在很多模式串不能拼在当前位置的,无效状态。所以可以用Trie树来优化转移。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <cctype>
#include <time.h> using namespace std; const int INF = <<;
const int MAXN = 1e5+;
const int MAXLEN = ;
const int MAXNODE = 1e5+;; struct Trie {
int ch[MAXNODE][];
int val[MAXNODE], use; inline void init() {
for (int i = ; i < ; i++) ch[][i] = ;
val[] = ;
use = ;
}
inline int New() {
for (int i = ; i < ; i++) ch[use][i] = ;
val[use] = ;
return use++;
}
inline int idx(char c) {
return c - 'a';
}
void insert(char str[], int v) {
int len = strlen(str);
int p = ;
for (int i = ; i < len; i++) {
int c = idx(str[i]);
if (!ch[p][c]) ch[p][c] = New();
p = ch[p][c];
}
val[p] = max(val[p], v);
}
int solve(char S[], int dp[]) {
int len = strlen(S);
for (int i = ; i <= len; i++) dp[i] = -;
dp[] = ;
for (int i = ; i < len; i++) {
if (dp[i]<) continue;
for (int j = i, p = ; j <= len; j++) {
int c = idx(S[j]);
if (val[p]) dp[j] = max(dp[j], dp[i]+val[p]);
p = ch[p][c];
if (p==) break;
}
}
return max(dp[len], );
}
}; Trie solver; char S[MAXN], P[MAXLEN];
int dp[MAXN];
int m, v; int main() {
#ifdef Phantom01
freopen("HNU13108.txt", "r", stdin);
#endif //Phantom01 while (scanf("%s", S)!=EOF) {
scanf("%d", &m);
solver.init();
for (int i = ; i < m; i++) {
scanf("%s%d", P, &v);
solver.insert(P, v);
}
printf("%d\n", solver.solve(S, dp));
} return ;
}
HNU 13108 Just Another Knapsack Problem DP + Trie树优化的更多相关文章
- UVALive - 3942 (DP + Trie树)
给出一个长度不超过300000的字符串 S,然后给出 n 个长度不超过100的字符串. 如果字符串可以多次使用,用这 n 个字符串组成 S 的方法数是多少? 比如样例中,abcd = a + b + ...
- FZU-2214 Knapsack problem(DP使用)
Problem 2214 Knapsack problem Accept: 863 Submit: 3347Time Limit: 3000 mSec Memory Limit : 327 ...
- Codeforces 615C Running Track(DP + Trie树)
题目大概说给两个串,问最少要用多少个第一个串的子串(可以翻转)拼成第二个串. UVa1401,一个道理..dp[i]表示前缀i拼接成功所需最少的子串,利用第一个串所有子串建立的Trie树往前枚举转移. ...
- UVa1401 Remember the Word(DP+Trie树)
题目给定一个字符串集合有几种方式拼成一个字符串. dp[i]表示stri...strlen-1的方案数 dp[len]=1 dp[i]=∑dp[j](stri...strj-1∈SET) 用集合的字符 ...
- 洛谷:P2292 [HNOI2004]L语言(DP+Trie树)
P2292 [HNOI2004]L语言 题目链接:https://www.luogu.org/problemnew/show/P2292 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有 ...
- CF1625D - Binary Spiders[trie树优化dp]
官方题解 题意:给数列a[],选择尽量多的数满足任意两个异或起来<=k 1625D - Binary Spiders 思路:首先,将数列排序得到,然后升序取得的值的任意两个最小值为相邻两个异或的 ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
- HDU4719-Oh My Holy FFF(DP线段树优化)
Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) T ...
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
题目大意:给一个长度为n的区间,m条线段序列,找出这个序列的一个最短子序列,使得区间完全被覆盖. 题目分析:这道题不难想,定义状态dp(i)表示用前 i 条线段覆盖区间1~第 i 线段的右端点需要的最 ...
随机推荐
- SASS概览
1.安装: sass需要使用ruby,首先安装ruby,之后: gem install sass 编译: sass input.scss output.css 2.快速入门: 变量: .scss 变量 ...
- 利用after和before伪类实现chrome浏览器tab选项卡斜边纯css无图制作笔记
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- ajax常用知识
同源地址:任意两个地址中的协议,域名,端口相同,称为同源地址 同源策略: 是浏览器的一种基本安全策略 不允许对非同源地址进行请求(ajax) ...
- 数组实例的 entries(),keys() 和 values()
数组实例的 entries(),keys() 和 values() entries(),keys()和values(),用于遍历数组.它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一 ...
- 5kcrm增加权限管理中的模块(签到统计)
1 首先在model表增加模块名称 2 在controll里增加方法 3 在授权的html增加表单
- jvm 虚拟机参数_堆内存分配
1.参数 -XX:+PrintGC 只要遇到 GC 就会打印日志 -XX:+UseSerialGC 配置串行回收器 -XX:+PrintGCDetails 查看详细信息,包括各个区的情况 -XX:+P ...
- shell如何更改当前工作路径
转载: http://imysqldba.blog.51cto.com/1222376/616805 shell 脚本执行有三种方法 bash 脚本名 sh 脚本名 chmod +x 脚本名 使用下面 ...
- Codeforces Round #261 (Div. 2)459A. Pashmak and Garden(数学题)
题目链接:http://codeforces.com/problemset/problem/459/A A. Pashmak and Garden time limit per test 1 seco ...
- linux下挂载ISCSI存储设备
安装 首先要在存储设备上做好RAID,设置好iSCSI 目标方(target). 这里主要说明iSCSI initiator的安装. 不同的操作系统对应各自的iSCSI initiator,以Redh ...
- android adb command
一.adb启动activity: $ adb shell$ am start -n {包(package)名}/{包名}.{活动(activity)名称} 如:启动浏览器 # am start -n ...