挺好的一道题目,我的做法是kmp+Dinic网络流。
kmp求子串在P中出现的次数,从而计算love值。
网络流主要用来处理最优解。
case2中p1的love值是8,p2的love值是7,最终T包含p1和p2,hate值也仅仅算一次。
这个题目难点在于思考为什么网络流的解法是合理,可以反证。从而导出最优解等于love的总和-最大流。
建图方法:
source连接p,初始容量为love值;
p连接s,初始容量为INF;
s连接destination,容量为hate值。
在最优解中,如果s到des的流量小于容量,则证明包含s的p都不被选择。即减去p的容量和。如果流量大于等于容量,则证明该直接去掉hate值。

 /* 3505 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct {
int l, h, len;
char s[];
int nxt[]; void getnext() {
int i = , j = -; nxt[] = -;
while (i < len) {
if (j==- || s[i]==s[j]) {
++i;
++j;
nxt[i] = j;
} else {
j = nxt[j];
}
}
} int kmp(char *d) {
int dlen = strlen(d);
int i = , j =;
int ret = ; while (i < dlen) {
if (d[i] == s[j]) {
++i;
++j;
} else {
j = nxt[j];
if (j == -) {
j = ;
++i;
}
}
if (j == len) {
++ret;
j = nxt[j];
}
} return ret;
} } node_t; typedef struct {
int v, f, nxt;
} edge_t; const int INF = 0x3f3f3f3f;
const int maxn = ;
const int maxv = maxn * ;
const int maxl = ;
const int maxe = 1e5+;
node_t nd[maxn];
bool M[maxn][maxn];
int score[maxn];
int head[maxv], head_[maxv];
edge_t E[maxe];
int dis[maxv];
int Q[maxv];
char s[maxl];
int nxt[maxl];
int sn, pn, m; int calc(int k) {
int ret = , cnt; rep(i, , sn+) {
cnt = nd[i].kmp(s);
if (cnt) {
ret += nd[i].l * cnt;
M[k][i] = true;
}
} return ret;
} void init() {
m = ;
memset(head, -, sizeof(head));
memset(M, false, sizeof(M));
} void addEdge(int u, int v, int f) {
E[m].v = v;
E[m].f = f;
E[m].nxt = head[u];
head[u] = m++; E[m].v = u;
E[m].f = ;
E[m].nxt = head[v];
head[v] = m++;
} bool bfs(int s, int t) {
int l = , r = ;
int u, v, k; Q[r++] = s;
memset(dis, , sizeof(dis));
dis[s] = ; while (l < r) {
u = Q[l++];
for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (!dis[v] && E[k].f) {
dis[v] = dis[u] + ;
if (v == t)
return false;
Q[r++] = v;
}
}
} return true;
} int dfs(int u, int t, int val) {
if (u==t || val==)
return val; int ret = ;
int v, tmp; for (int& k=head_[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (E[k].f && dis[v]==dis[u]+ && (tmp=dfs(v, t, min(val, E[k].f)))>) {
E[k].f -= tmp;
E[k^].f += tmp;
ret += tmp;
val -= tmp;
if (val == )
return ret;
}
} return ret;
} int Dinic(int s, int t) {
int ret = , tmp; while () {
if (bfs(s, t))
break; memcpy(head_, head, sizeof(head));
while () {
tmp = dfs(s, t, INF);
if (tmp == )
break;
ret += tmp;
}
} return ret;
} void Build() {
int s = ;
int t = maxv - ; rep(i, , sn+) {
addEdge(i, t, nd[i].h);
} rep(i, , pn+) {
addEdge(s, sn+i, score[i]);
rep(j, , sn+) {
if (M[i][j])
addEdge(sn+i, j, INF);
}
}
} int solve() {
int ret = ; rep(i, , pn+) {
scanf("%s", s);
score[i] = calc(i);
ret += score[i];
} Build();
int tmp = Dinic(, maxv-);
ret -= tmp;
#ifndef ONLINE_JUDGE
printf("maxflow = %d\n", tmp);
#endif return ret;
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t;
int ans; scanf("%d", &t);
rep(tt, , t+) {
init();
scanf("%d %d", &sn, &pn);
rep(i, , sn+) {
scanf("%d %d %s", &nd[i].l, &nd[i].h, nd[i].s);
nd[i].len = strlen(nd[i].s);
nd[i].getnext();
}
ans = solve();
printf("Case %d: %d\n", tt, ans);
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【HDOJ】3505 Writing Robot的更多相关文章

  1. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  2. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  3. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  4. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

  5. 【HDOJ】【2829】Lawrence

    DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...

  6. 【HDOJ】【3415】Max Sum of Max-K-sub-sequence

    DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...

  7. 【HDOJ】【3530】Subsequence

    DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...

  8. 【HDOJ】【3068】最长回文

    Manacher算法 Manacher模板题…… //HDOJ 3068 #include<cstdio> #include<cstring> #include<cstd ...

  9. 【HDOJ】【1512】Monkey King

    数据结构/可并堆 啊……换换脑子就看了看数据结构……看了一下左偏树和斜堆,鉴于左偏树不像斜堆可能退化就写了个左偏树. 左偏树介绍:http://www.cnblogs.com/crazyac/arti ...

随机推荐

  1. ubuntu恢复rm -rf误删文件

    使用extundelete工具 sudo apt-get install extundelete 恢复操作命令 首先需要umount或者read only 分区  umount /dev/partit ...

  2. Appium Python Driver Api

  3. IOS开发之NSObject协议类方法说明

    oc中NSObject类是所有类的基类,所有类都要继承自它,那么它的方法就显得特别重要,因为所有类都会有这些基本的方法. 看看oc的源码中NSObject是这样定义的: @interface NSOb ...

  4. 【html】【20】高级篇--轮播图[聚焦]

    下载: http://sc.chinaz.com/jiaoben/151204445580.htm 效果: html <!doctype html> <html> <he ...

  5. C# ACM poj1003

    这题很有内涵,先用简单方法 public static void acm1003(double a) { ) { return; } ; ) { / b; a = a - c; b++; } Cons ...

  6. 新安装Eclipse后的一些配置

    配置护眼的背景色 Window-> Preferences-> General-> Editors-> Text Editors: Appearance color optio ...

  7. NOIP(提高组)DAY1国王游戏

    问题描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这n位大臣排成一排,国王站在队伍的最前面.排好队 ...

  8. POJ 2127 Greatest Common Increasing Subsequence -- 动态规划

    题目地址:http://poj.org/problem?id=2127 Description You are given two sequences of integer numbers. Writ ...

  9. MySql启动提示:The server quit without updating PID file(…)失败

    在网上找了很多 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限解决方法 :给予权限,执行 “chown -R mysql:mysql /var/data”  ...

  10. jquery ajax php 无刷新上传文件 带 遮罩 进度条 效果的哟

    在很多项目中都会叫用户上传东西这些的,自从接触了jquery 和ajax之后就不管做什么,首先都会想到这个,我这个人呢?是比较重视客户体验的,这次我这边负责的是后台板块,然后就有一块是要求用户上传照片 ...