挺好的一道题目,我的做法是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值。

  1. /* 3505 */
  2. #include <iostream>
  3. #include <string>
  4. #include <map>
  5. #include <queue>
  6. #include <set>
  7. #include <stack>
  8. #include <vector>
  9. #include <deque>
  10. #include <algorithm>
  11. #include <cstdio>
  12. #include <cmath>
  13. #include <ctime>
  14. #include <cstring>
  15. #include <climits>
  16. #include <cctype>
  17. #include <cassert>
  18. #include <functional>
  19. #include <iterator>
  20. #include <iomanip>
  21. using namespace std;
  22. //#pragma comment(linker,"/STACK:102400000,1024000")
  23.  
  24. #define sti set<int>
  25. #define stpii set<pair<int, int> >
  26. #define mpii map<int,int>
  27. #define vi vector<int>
  28. #define pii pair<int,int>
  29. #define vpii vector<pair<int,int> >
  30. #define rep(i, a, n) for (int i=a;i<n;++i)
  31. #define per(i, a, n) for (int i=n-1;i>=a;--i)
  32. #define clr clear
  33. #define pb push_back
  34. #define mp make_pair
  35. #define fir first
  36. #define sec second
  37. #define all(x) (x).begin(),(x).end()
  38. #define SZ(x) ((int)(x).size())
  39. #define lson l, mid, rt<<1
  40. #define rson mid+1, r, rt<<1|1
  41.  
  42. typedef struct {
  43. int l, h, len;
  44. char s[];
  45. int nxt[];
  46.  
  47. void getnext() {
  48. int i = , j = -;
  49.  
  50. nxt[] = -;
  51. while (i < len) {
  52. if (j==- || s[i]==s[j]) {
  53. ++i;
  54. ++j;
  55. nxt[i] = j;
  56. } else {
  57. j = nxt[j];
  58. }
  59. }
  60. }
  61.  
  62. int kmp(char *d) {
  63. int dlen = strlen(d);
  64. int i = , j =;
  65. int ret = ;
  66.  
  67. while (i < dlen) {
  68. if (d[i] == s[j]) {
  69. ++i;
  70. ++j;
  71. } else {
  72. j = nxt[j];
  73. if (j == -) {
  74. j = ;
  75. ++i;
  76. }
  77. }
  78. if (j == len) {
  79. ++ret;
  80. j = nxt[j];
  81. }
  82. }
  83.  
  84. return ret;
  85. }
  86.  
  87. } node_t;
  88.  
  89. typedef struct {
  90. int v, f, nxt;
  91. } edge_t;
  92.  
  93. const int INF = 0x3f3f3f3f;
  94. const int maxn = ;
  95. const int maxv = maxn * ;
  96. const int maxl = ;
  97. const int maxe = 1e5+;
  98. node_t nd[maxn];
  99. bool M[maxn][maxn];
  100. int score[maxn];
  101. int head[maxv], head_[maxv];
  102. edge_t E[maxe];
  103. int dis[maxv];
  104. int Q[maxv];
  105. char s[maxl];
  106. int nxt[maxl];
  107. int sn, pn, m;
  108.  
  109. int calc(int k) {
  110. int ret = , cnt;
  111.  
  112. rep(i, , sn+) {
  113. cnt = nd[i].kmp(s);
  114. if (cnt) {
  115. ret += nd[i].l * cnt;
  116. M[k][i] = true;
  117. }
  118. }
  119.  
  120. return ret;
  121. }
  122.  
  123. void init() {
  124. m = ;
  125. memset(head, -, sizeof(head));
  126. memset(M, false, sizeof(M));
  127. }
  128.  
  129. void addEdge(int u, int v, int f) {
  130. E[m].v = v;
  131. E[m].f = f;
  132. E[m].nxt = head[u];
  133. head[u] = m++;
  134.  
  135. E[m].v = u;
  136. E[m].f = ;
  137. E[m].nxt = head[v];
  138. head[v] = m++;
  139. }
  140.  
  141. bool bfs(int s, int t) {
  142. int l = , r = ;
  143. int u, v, k;
  144.  
  145. Q[r++] = s;
  146. memset(dis, , sizeof(dis));
  147. dis[s] = ;
  148.  
  149. while (l < r) {
  150. u = Q[l++];
  151. for (k=head[u]; k!=-; k=E[k].nxt) {
  152. v = E[k].v;
  153. if (!dis[v] && E[k].f) {
  154. dis[v] = dis[u] + ;
  155. if (v == t)
  156. return false;
  157. Q[r++] = v;
  158. }
  159. }
  160. }
  161.  
  162. return true;
  163. }
  164.  
  165. int dfs(int u, int t, int val) {
  166. if (u==t || val==)
  167. return val;
  168.  
  169. int ret = ;
  170. int v, tmp;
  171.  
  172. for (int& k=head_[u]; k!=-; k=E[k].nxt) {
  173. v = E[k].v;
  174. if (E[k].f && dis[v]==dis[u]+ && (tmp=dfs(v, t, min(val, E[k].f)))>) {
  175. E[k].f -= tmp;
  176. E[k^].f += tmp;
  177. ret += tmp;
  178. val -= tmp;
  179. if (val == )
  180. return ret;
  181. }
  182. }
  183.  
  184. return ret;
  185. }
  186.  
  187. int Dinic(int s, int t) {
  188. int ret = , tmp;
  189.  
  190. while () {
  191. if (bfs(s, t))
  192. break;
  193.  
  194. memcpy(head_, head, sizeof(head));
  195. while () {
  196. tmp = dfs(s, t, INF);
  197. if (tmp == )
  198. break;
  199. ret += tmp;
  200. }
  201. }
  202.  
  203. return ret;
  204. }
  205.  
  206. void Build() {
  207. int s = ;
  208. int t = maxv - ;
  209.  
  210. rep(i, , sn+) {
  211. addEdge(i, t, nd[i].h);
  212. }
  213.  
  214. rep(i, , pn+) {
  215. addEdge(s, sn+i, score[i]);
  216. rep(j, , sn+) {
  217. if (M[i][j])
  218. addEdge(sn+i, j, INF);
  219. }
  220. }
  221. }
  222.  
  223. int solve() {
  224. int ret = ;
  225.  
  226. rep(i, , pn+) {
  227. scanf("%s", s);
  228. score[i] = calc(i);
  229. ret += score[i];
  230. }
  231.  
  232. Build();
  233. int tmp = Dinic(, maxv-);
  234. ret -= tmp;
  235. #ifndef ONLINE_JUDGE
  236. printf("maxflow = %d\n", tmp);
  237. #endif
  238.  
  239. return ret;
  240. }
  241.  
  242. int main() {
  243. ios::sync_with_stdio(false);
  244. #ifndef ONLINE_JUDGE
  245. freopen("data.in", "r", stdin);
  246. freopen("data.out", "w", stdout);
  247. #endif
  248.  
  249. int t;
  250. int ans;
  251.  
  252. scanf("%d", &t);
  253. rep(tt, , t+) {
  254. init();
  255. scanf("%d %d", &sn, &pn);
  256. rep(i, , sn+) {
  257. scanf("%d %d %s", &nd[i].l, &nd[i].h, nd[i].s);
  258. nd[i].len = strlen(nd[i].s);
  259. nd[i].getnext();
  260. }
  261. ans = solve();
  262. printf("Case %d: %d\n", tt, ans);
  263. }
  264.  
  265. #ifndef ONLINE_JUDGE
  266. printf("time = %d.\n", (int)clock());
  267. #endif
  268.  
  269. return ;
  270. }

【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. Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法

    Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...

  2. ###学习《C++ Primer》- 1

    点击查看Evernote原文. #@author: gr #@date: 2014-09-30 #@email: forgerui@gmail.com 记录读书过程中一些知识点.可能不系统,:-). ...

  3. infopath 之绑定列表 数据源

    在psd中启动infopath更新表单模版 注:虽然可能在infopath design中预览的时候会报错说是跨域数据不能加载,别理他 继续发布上站点就不会有这个错误了. 绑定list后效果: 参考u ...

  4. From MSI to WiX, Part 1 - Required properties, by Alex Shevchuk

    Following content is directly reprinted from From MSI to WiX, Part 1 - Required properties Author: A ...

  5. C++对象创建与释放

    创建对象有以下四种形式: #include <iostream> using namespace std; class A{ private: int i; public: A(){ co ...

  6. Ubuntu 下部署asp.net运行环境

    在Ubuntu下部署asp.net运行环境,网上教程很多,基本都是编译Mono源码,然后安装jexus.但是可能是我最近RP不太好,编译Mono源码一直都是失败,无奈之下只好找另外的方法安装了. 网上 ...

  7. TCP UDP 协议的选择

    行业应用中TCP/IP传输协议和UDP协议的选择! 中国移动.中国联通推行的GPRS网络.CDMA网络已覆盖大量的区域,通过无线网络实现数据传输成为可 能.无线Modem采用GPRS.CDMA模块通过 ...

  8. 我的第一个python代码实践:Trie树

    Trie树 不解析,  本园很多博文有提到. 直接上代码: #coding:utf-8 ''' create on 2013-07-30 @author :HuangYanQiang ''' LETT ...

  9. Spring核心框架 - AOP之动态代理机制

    动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码.动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类. ...

  10. AJax跨域请求百度音乐接口数据展示页面

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...