• [swust 1741] 最长递增子序列问题(DP,最大流)


    题目链接:https://www.oj.swust.edu.cn/problem/show/1741

    此题同上,但是多一个问:x1和xn能用多次。

    解法一样,只不过这两个点相关的边都是inf就行了。这样可以表示能无限用。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef struct Edge {
      5     int u, v, w, next;
      6 }Edge;
      7 
      8 const int inf = 0x7f7f7f7f;
      9 const int maxn = 6660;
     10 
     11 int cnt, dhead[maxn];
     12 int cur[maxn], dd[maxn];
     13 Edge dedge[maxn<<8];
     14 int S, T, N;
     15 
     16 void init() {
     17     memset(dhead, -1, sizeof(dhead));
     18     for(int i = 0; i < maxn; i++) dedge[i].next = -1;
     19     S = 0; cnt = 0;
     20 }
     21 
     22 void adde(int u, int v, int w, int c1=0) {
     23     dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w; 
     24     dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
     25     dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1; 
     26     dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
     27 }
     28 
     29 bool bfs(int s, int t, int n) {
     30     queue<int> q;
     31     for(int i = 0; i < n; i++) dd[i] = inf;
     32     dd[s] = 0;
     33     q.push(s);
     34     while(!q.empty()) {
     35         int u = q.front(); q.pop();
     36         for(int i = dhead[u]; ~i; i = dedge[i].next) {
     37             if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) {
     38                 dd[dedge[i].v] = dd[u] + 1;
     39                 if(dedge[i].v == t) return 1;
     40                 q.push(dedge[i].v);
     41             }
     42         }
     43     }
     44     return 0;
     45 }
     46 
     47 int dinic(int s, int t, int n) {
     48     int st[maxn], top;
     49     int u;
     50     int flow = 0;
     51     while(bfs(s, t, n)) {
     52         for(int i = 0; i < n; i++) cur[i] = dhead[i];
     53         u = s; top = 0;
     54         while(cur[s] != -1) {
     55             if(u == t) {
     56                 int tp = inf;
     57                 for(int i = top - 1; i >= 0; i--) {
     58                     tp = min(tp, dedge[st[i]].w);
     59                 }
     60                 flow += tp;
     61                 for(int i = top - 1; i >= 0; i--) {
     62                     dedge[st[i]].w -= tp;
     63                     dedge[st[i] ^ 1].w += tp;
     64                     if(dedge[st[i]].w == 0) top = i;
     65                 }
     66                 u = dedge[st[top]].u;
     67             }
     68             else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) {
     69                 st[top++] = cur[u];
     70                 u = dedge[cur[u]].v;
     71             }
     72             else {
     73                 while(u != s && cur[u] == -1) {
     74                     u = dedge[st[--top]].u;
     75                 }
     76                 cur[u] = dedge[cur[u]].next;
     77             }
     78         }
     79     }
     80     return flow;
     81 }
     82 
     83 int n;
     84 int x[maxn];
     85 int dp[maxn];
     86 int ret;
     87 
     88 void work1() {
     89     ret = 0;
     90     memset(dp, 0, sizeof(dp));
     91     for(int i = 1; i <= n; i++) {
     92         dp[i] = 1;
     93         for(int j = 1; j <= i; j++) {
     94             if(x[i] > x[j]) dp[i] = max(dp[i], dp[j]+1);
     95         }
     96         ret = max(ret, dp[i]);
     97     }
     98     printf("%d
    ", ret);
     99 }
    100 
    101 void work2() {
    102     if(ret == 1) {
    103         printf("%d
    ", n);
    104         return;
    105     }
    106     init();
    107     S = 0, T = 2 * n + 1, N = T + 1;
    108     for(int i = 1; i <= n; i++) {
    109         adde(i, i+n, 1);
    110         if(dp[i] == 1) adde(S, i, 1);
    111         if(dp[i] == ret) adde(i+n, T, 1);
    112     }
    113     for(int i = 2; i <= n; i++) {
    114         for(int j = 1; j < i; j++) {
    115             if(x[i] > x[j] && dp[i] == dp[j] + 1) {
    116                 adde(j+n, i, 1);
    117             }
    118         }
    119     }
    120     cout << dinic(S, T, N) << endl;
    121 }
    122 
    123 void work3() {
    124     if(ret == 1) {
    125         printf("%d
    ", n);
    126         return;
    127     }
    128     init();
    129     S = 0, T = 2 * n + 1, N = T + 1;
    130     for(int i = 1; i <= n; i++) {
    131         if(i == 1 || i == n) {
    132             adde(i, i+n, inf);
    133             if(dp[i] == 1) adde(S, i, inf);
    134             if(dp[i] == ret) adde(i+n, T, inf);
    135         }
    136         else {
    137             adde(i, i+n, 1);
    138             if(dp[i] == 1) adde(S, i, 1);
    139             if(dp[i] == ret) adde(i+n, T, 1);
    140         }
    141     }
    142     for(int i = 2; i <= n; i++) {
    143         for(int j = 1; j < i; j++) {
    144             if(x[i] > x[j] && dp[i] == dp[j] + 1) {
    145                 adde(j+n, i, 1);
    146             }
    147         }
    148     }
    149     cout << dinic(S, T, N) << endl;
    150 }
    151 
    152 int main() {
    153     // freopen("in", "r", stdin);
    154     while(~scanf("%d",&n)) {
    155         init();
    156         for(int i = 1; i <= n; i++) scanf("%d", &x[i]);
    157         work1(); work2();
    158     }
    159     return 0;
    160 }
  • 相关阅读:
    关于运行和调试的困惑
    初识函数
    Php的基本语法
    Apache的安装
    php的初步了解
    线程笔记
    Matlab笔记
    matlab取模与取余
    DialogFragment学习笔记
    MVP学习笔记——参考Google官方demo
  • 原文地址:https://www.cnblogs.com/kirai/p/6832434.html
Copyright © 2020-2023  润新知