【HDOJ】3505 Writing Robot
挺好的一道题目,我的做法是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的更多相关文章
- 【HDOJ】4729 An Easy Problem for Elfness
其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...
- 【HDOJ】【3506】Monkey Party
DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...
- 【HDOJ】【3516】Tree Construction
DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...
- 【HDOJ】【3480】Division
DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...
- 【HDOJ】【2829】Lawrence
DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...
- 【HDOJ】【3415】Max Sum of Max-K-sub-sequence
DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...
- 【HDOJ】【3530】Subsequence
DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...
- 【HDOJ】【3068】最长回文
Manacher算法 Manacher模板题…… //HDOJ 3068 #include<cstdio> #include<cstring> #include<cstd ...
- 【HDOJ】【1512】Monkey King
数据结构/可并堆 啊……换换脑子就看了看数据结构……看了一下左偏树和斜堆,鉴于左偏树不像斜堆可能退化就写了个左偏树. 左偏树介绍:http://www.cnblogs.com/crazyac/arti ...
随机推荐
- Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法
Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...
- ###学习《C++ Primer》- 1
点击查看Evernote原文. #@author: gr #@date: 2014-09-30 #@email: forgerui@gmail.com 记录读书过程中一些知识点.可能不系统,:-). ...
- infopath 之绑定列表 数据源
在psd中启动infopath更新表单模版 注:虽然可能在infopath design中预览的时候会报错说是跨域数据不能加载,别理他 继续发布上站点就不会有这个错误了. 绑定list后效果: 参考u ...
- 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 ...
- C++对象创建与释放
创建对象有以下四种形式: #include <iostream> using namespace std; class A{ private: int i; public: A(){ co ...
- Ubuntu 下部署asp.net运行环境
在Ubuntu下部署asp.net运行环境,网上教程很多,基本都是编译Mono源码,然后安装jexus.但是可能是我最近RP不太好,编译Mono源码一直都是失败,无奈之下只好找另外的方法安装了. 网上 ...
- TCP UDP 协议的选择
行业应用中TCP/IP传输协议和UDP协议的选择! 中国移动.中国联通推行的GPRS网络.CDMA网络已覆盖大量的区域,通过无线网络实现数据传输成为可 能.无线Modem采用GPRS.CDMA模块通过 ...
- 我的第一个python代码实践:Trie树
Trie树 不解析, 本园很多博文有提到. 直接上代码: #coding:utf-8 ''' create on 2013-07-30 @author :HuangYanQiang ''' LETT ...
- Spring核心框架 - AOP之动态代理机制
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码.动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类. ...
- AJax跨域请求百度音乐接口数据展示页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...