• 【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值。

      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[54];
     45     int nxt[54];
     46     
     47     void getnext() {
     48         int i = 0, j = -1;
     49         
     50         nxt[0] = -1;
     51         while (i < len) {
     52             if (j==-1 || 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 = 0, j =0;
     65         int ret = 0;
     66         
     67         while (i < dlen) {
     68             if (d[i] == s[j]) {
     69                 ++i;
     70                 ++j;
     71             } else {
     72                 j = nxt[j];
     73                 if (j == -1) {
     74                     j = 0;
     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 = 155;
     95 const int maxv = maxn * 2;
     96 const int maxl = 1005;
     97 const int maxe = 1e5+5;
     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 = 0, cnt;
    111     
    112     rep(i, 1, sn+1) {
    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 = 0;
    125     memset(head, -1, 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 = 0;
    137     E[m].nxt = head[v];
    138     head[v] = m++;
    139 }
    140 
    141 bool bfs(int s, int t) {
    142     int l = 0, r = 0;
    143     int u, v, k;
    144     
    145     Q[r++] = s;
    146     memset(dis, 0, sizeof(dis));
    147     dis[s] = 1;
    148     
    149     while (l < r) {
    150         u = Q[l++];
    151         for (k=head[u]; k!=-1; k=E[k].nxt) {
    152             v = E[k].v;
    153             if (!dis[v] && E[k].f) {
    154                 dis[v] = dis[u] + 1;
    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==0)
    167         return val;
    168     
    169     int ret = 0;
    170     int v, tmp;
    171     
    172     for (int& k=head_[u]; k!=-1; k=E[k].nxt) {
    173         v = E[k].v;
    174         if (E[k].f && dis[v]==dis[u]+1 && (tmp=dfs(v, t, min(val, E[k].f)))>0) {
    175             E[k].f -= tmp;
    176             E[k^1].f += tmp;
    177             ret += tmp;
    178             val -= tmp;
    179             if (val == 0)
    180                 return ret;
    181         }
    182     }
    183     
    184     return ret;
    185 }
    186 
    187 int Dinic(int s, int t) {
    188     int ret = 0, tmp;
    189     
    190     while (1) {
    191         if (bfs(s, t))
    192             break;
    193         
    194         memcpy(head_, head, sizeof(head));
    195         while (1) {
    196             tmp = dfs(s, t, INF);
    197             if (tmp == 0)
    198                 break;
    199             ret += tmp;
    200         }
    201     }
    202     
    203     return ret;
    204 }
    205 
    206 void Build() {
    207     int s = 0;
    208     int t = maxv - 1;
    209     
    210     rep(i, 1, sn+1) {
    211         addEdge(i, t, nd[i].h);
    212     }
    213     
    214     rep(i, 1, pn+1) {
    215         addEdge(s, sn+i, score[i]);
    216         rep(j, 1, sn+1) {
    217             if (M[i][j])
    218                 addEdge(sn+i, j, INF);
    219         }
    220     }
    221 }
    222 
    223 int solve() {
    224     int ret = 0;
    225     
    226     rep(i, 1, pn+1) {
    227         scanf("%s", s);
    228         score[i] = calc(i);
    229         ret += score[i];
    230     }
    231     
    232     Build();
    233     int tmp = Dinic(0, maxv-1);
    234     ret -= tmp;
    235     #ifndef ONLINE_JUDGE
    236         printf("maxflow = %d
    ", 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, 1, t+1) {
    254         init();
    255         scanf("%d %d", &sn, &pn);
    256         rep(i, 1, sn+1) {
    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
    ", tt, ans);
    263     }
    264     
    265     #ifndef ONLINE_JUDGE
    266         printf("time = %d.
    ", (int)clock());
    267     #endif
    268     
    269     return 0;
    270 }
  • 相关阅读:
    统计知识选讲(二)——主成分分析(PCA)的推导和应用
    统计知识选讲(一)——主成分分析(PCA)的思想
    数模学习笔记(八)——遗传算法
    数模学习笔记(六)——灰色系统
    数模学习笔记(五)——BP神经网络
    数模学习笔记(四)——AHP
    数模学习笔记(三)
    数模学习笔记(二)
    推荐决策 对比user-based 和item-based推荐算法
    Mysql事件学习
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5068586.html
Copyright © 2020-2023  润新知