zoukankan      html  css  js  c++  java
  • 【HDOJ6611】K Subsequence(费用流)

    题意:给定一个长为n的正整数序列,要求从中取出至多k个不下降序列,使得它们的和最大,求这个和

    n<=2e3,k<=10,a[i]<=1e5

    思路:极其考验模板,反正我的spfa和zkw都挂了,就拿这题std做dijkstra费用流的板子了

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 typedef pair<ll,ll>P;
     11 #define N  10000
     12 #define M  2100000
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pb push_back
     17 #define pi acos(-1)
     18 #define mem(a,b) memset(a,b,sizeof(a))
     19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     21 #define lowbit(x) x&(-x)
     22 #define Rand (rand()*(1<<16)+rand())
     23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     24 #define ls p<<1
     25 #define rs p<<1|1
     26 
     27 const int MOD=998244353,inv2=(MOD+1)/2;
     28       double eps=1e-4;
     29       int INF=0x7fffffff;;
     30       ll inf=5e13;
     31       int dx[4]={-1,1,0,0};
     32       int dy[4]={0,0,-1,1};
     33 
     34 struct edge
     35 {
     36     int to,cap,cost,rev;
     37     edge(){}
     38     edge(int a,int b,int c,int d):
     39     to(a),cap(b),cost(c),rev(d){}
     40 };
     41 
     42 int read()
     43 {
     44    int v=0,f=1;
     45    char c=getchar();
     46    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     47    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     48    return v*f;
     49 }
     50 
     51 struct MCMF
     52 {
     53     int V,h[N],dis[N],preV[N],preE[N];
     54     vector<edge> g[N];
     55 
     56     void init(int n)
     57     {
     58         V=n;
     59         rep(i,0,V) g[i].clear();
     60     }
     61 
     62     void add(int u,int v,int cap,int cost)
     63     {
     64         g[u].pb(edge(v,cap,cost,g[v].size()));
     65         g[v].pb(edge(u,0,-cost,g[u].size()-1));
     66     }
     67 
     68     int minc_mf(int S,int T,int f,int &flow)
     69     {
     70         int res=0;
     71         fill(h,h+1+V,0);
     72         while(f)
     73         {
     74             priority_queue <PII,vector<PII>, greater<PII> > q;
     75             fill(dis,dis+1+V,INF);
     76             dis[S]=0;
     77             q.push(MP(0,S));
     78             while(!q.empty())
     79             {
     80                 PII now=q.top(); q.pop();
     81                 int u=now.se;
     82                 if(dis[u]<now.fi) continue;
     83                 for(int i=0;i<g[u].size();i++)
     84                 {
     85                     edge e=g[u][i];
     86                     int v=e.to;
     87                     if(e.cap>0&&dis[v]>dis[u]+e.cost+h[u]-h[v])
     88                     {
     89                         dis[v]=dis[u]+e.cost+h[u]-h[v];
     90                         preV[v]=u;
     91                         preE[v]=i;
     92                         q.push(MP(dis[v],v));
     93                     }
     94 
     95                 }
     96             }
     97             if(dis[T]==INF) break;
     98             rep(i,0,V) h[i]+=dis[i];
     99             int t=f,k=T;
    100             while(k!=S)
    101             {
    102                 int e=preE[k];
    103                 t=min(t,g[preV[k]][preE[k]].cap);
    104                 k=preV[k];
    105             }
    106             f-=t; flow+=t; res+=t*h[T];
    107             k=T;
    108             while(k!=S)
    109             {
    110                 edge &e=g[preV[k]][preE[k]];
    111                 e.cap-=t;
    112                 g[k][e.rev].cap+=t;
    113                 k=preV[k];
    114             }
    115         }
    116         return res;
    117     }
    118 }mcmf;
    119 
    120 int num[N][2],a[N],S,T,s,flow;
    121 
    122 int main()
    123 {
    124     int cas=read();
    125     s=0;
    126     while(cas--)
    127     {
    128         int n=read(),k=read();
    129         rep(i,1,n) a[i]=read();
    130         s=0;
    131         rep(i,1,n)
    132         {
    133             num[i][0]=++s;
    134             num[i][1]=++s;
    135         }
    136         S=++s; s++; T=++s;
    137         mcmf.init(s);
    138         mcmf.add(S,S+1,k,0);
    139         rep(i,1,n) mcmf.add(S+1,num[i][0],1,0);
    140         rep(i,1,n) mcmf.add(num[i][0],num[i][1],1,-a[i]);
    141         rep(i,1,n)
    142          rep(j,i+1,n)
    143           if(a[j]>=a[i]) mcmf.add(num[i][1],num[j][0],1,0);
    144         rep(i,1,n) mcmf.add(num[i][1],T,1,0);
    145         flow=0;
    146         int ans=-mcmf.minc_mf(S,T,INF,flow);
    147         printf("%d
    ",ans);
    148     }
    149     return 0;
    15nb0 }

     无敌zyd的优化建图,思路是每个i都只与后面有可能构成最优解的j连边,最坏情况下没有任何改进,但好像因为a[i]是随机数据跑的飞快

      1 #pragma GCC optimize("O3")
      2 #pragma G++ optimize("O3")
      3 #include <queue>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <iostream>
      7 #include <algorithm>
      8 #define rep(i,l,r) for(int i=l;i<=r;++i)
      9 #define per(i,l,r) for(int i=l;i>=r;--i)
     10 using namespace std;
     11 
     12 
     13 const int N = 10000, M=100000;
     14 const int INF = 1e9;
     15 int n,m;
     16 int a[M];
     17 
     18 struct EG {
     19     int a, b, c, d, e;
     20 } eg[M];
     21 int head[N], en, S, T, SS;
     22 int flow, cost;
     23 int dis[N], pre[N], rem[N];
     24 bool inq[N];
     25 void insert(int u, int v, int w, int z) {
     26     eg[++en] = (EG) {v, head[u], w, z, u}; head[u] = en;
     27     eg[++en] = (EG) {u, head[v], 0, -z, v}; head[v] = en;
     28 }
     29 void Clear() {
     30     memset(head, 0, sizeof head);
     31     en = 1;
     32 }
     33 bool Spfa() {
     34     for (int i = 1; i <= SS; i++) dis[i] = INF, inq[i] = 0;
     35     dis[S] = 0;
     36     inq[S] = 1;
     37     queue<int> Q; Q.push(S);
     38     pre[S] = 0, rem[S] = INF;
     39     while (!Q.empty()) {
     40         int u = Q.front(); Q.pop();
     41         inq[u] = 0;
     42         for (int e = head[u]; e; e = eg[e].b) {
     43             int v = eg[e].a;
     44             if (eg[e].c > 0 && dis[u] + eg[e].d < dis[v]) {
     45                 dis[v] = dis[u] + eg[e].d;
     46                 pre[v] = e;
     47                 rem[v] = min(rem[u], eg[e].c);
     48                 if (!inq[v]) {
     49                     inq[v] = 1;
     50                     Q.push(v);
     51                 }
     52             }
     53         }
     54     }
     55     if (dis[T] == INF) return 0;
     56     flow += rem[T];
     57     cost += dis[T] * rem[T];
     58     int u = T;
     59     while (u != S) {
     60         eg[pre[u]].c -= rem[T];
     61         eg[pre[u] ^ 1].c += rem[T];
     62         u = eg[pre[u]].e;
     63     }
     64     return 1;
     65 }
     66 void MinCost() {
     67     flow = cost = 0;
     68     while (Spfa());
     69 }
     70 
     71 int main() {
     72     //freopen("a.txt","r",stdin);
     73 
     74     int test_;
     75     cin>>test_;
     76     while (test_--) {
     77         scanf("%d%d",&n,&m);
     78         rep(i,1,n) scanf("%d",a+i);
     79 
     80 
     81         Clear();
     82         S = n * 2 + 10, T = S + 1, SS = T + 1;
     83         for (int i = 1; i <= n; i++)
     84         {
     85             insert(i, i + n, 1, -a[i]);
     86             insert(i, i + n, m, 0);
     87             int mx = INF;
     88             for (int j = i + 1; j <= n; j++)
     89             {
     90                 if (a[j] < mx && a[j] >= a[i])
     91                 {
     92                     insert(i + n, j, INF, 0);
     93                     mx = a[j];
     94                 }
     95             }
     96         }
     97         insert(S, SS, m, 0);
     98         for (int i = 1; i <= n; i++)
     99         {
    100             insert(SS, i, 1, 0);
    101             insert(i + n, T, 1, 0);
    102         }
    103         MinCost();
    104         printf("%d
    ", -cost);
    105     }
    106 }
  • 相关阅读:
    基于微服务架构的RBAC权限管理系统
    用C#实现基于(OpenId Connect)的单点登录与RBAC权限验证(SSO,OIDC,RBAC)
    量化分析基础
    Ocelot 发现服务总是失败的解决办法
    windows 下安装 theano 及配置 gpu
    python scrapy 爬虫 初学
    layer弹出层框架alert与msg详解
    Workerman-文件监控-牛刀小试
    ECharts 初体验
    实验楼 linux 学习
  • 原文地址:https://www.cnblogs.com/myx12345/p/11608725.html
Copyright © 2011-2022 走看看