• bzoj 1283 序列


    题目传送门

      传送门

    题目大意

      给定一个长度为$n$的序列,要求选出一些数使得原序列中每$m$个连续的数中不超过$K$个被选走。问最大的可能的和。

      感觉建图好妙啊。。

      考虑把问题转化成选$m$次数,每次选出一个子序列, 要求两次选择的数的下标差至少为$m$。

      这个很容易建图就能做。$i$向$min{T, i + m}$连边,容量为1,费用为$a_i$。$i$向$i + 1$连边容量为1,费用为0.

    Code

      1 /**
      2  * bzoj
      3  * Problem#1283
      4  * Accepted
      5  * Time: 232ms
      6  * Memory: 1436k
      7  */
      8 #include <iostream>
      9 #include <cstdlib>
     10 #include <cstdio>
     11 #include <queue>
     12 using namespace std;
     13 typedef bool boolean;
     14 
     15 template <typename T>
     16 void pfill(T* pst, const T* ped, T val) {
     17     for ( ; pst != ped; *(pst++) = val);
     18 }
     19 
     20 typedef class Edge {
     21     public:
     22         int ed, nx, r, c;
     23 
     24         Edge(int ed = 0, int nx = 0, int r = 0, int c = 0) : ed(ed), nx(nx), r(r), c(c) {    } 
     25 } Edge;
     26 
     27 typedef class MapManager {
     28     public:
     29         int* h;
     30         vector<Edge> es;
     31 
     32         MapManager() {    }
     33         MapManager(int n) {
     34             h = new int[(n + 1)];
     35             pfill(h, h + n + 1, -1);
     36         }
     37 
     38         void addEdge(int u, int v, int r, int c) {
     39             es.push_back(Edge(v, h[u], r, c));
     40             h[u] = (signed) es.size() - 1;
     41         }
     42 
     43         void addArc(int u, int v, int cap, int c) {
     44             addEdge(u, v, cap, c);
     45             addEdge(v, u, 0, -c);
     46         }
     47 
     48         Edge& operator [] (int p) {
     49             return es[p];
     50         }
     51 } MapManager;
     52 
     53 const signed int inf = (signed) (~0u >> 1);
     54 
     55 typedef class Graph {
     56     public:
     57         int S, T;
     58         MapManager g;
     59         
     60         int *le;
     61         int *f, *mf;
     62         boolean *vis;
     63 
     64         Graph() {    }
     65         // be sure T is the last node
     66         Graph(int S, int T) {
     67             this->S = S;
     68             this->T = T;
     69             f = new int[(T + 1)];
     70             le = new int[(T + 1)];
     71             mf = new int[(T + 1)];
     72             vis = new boolean[(T + 1)];
     73             pfill(vis, vis + T, false);
     74         }
     75         
     76         int spfa() {
     77             queue<int> que;
     78             pfill(f, f + T + 1, -inf);
     79             que.push(S);
     80             f[S] = 0, le[S] = -1, mf[S] = inf;
     81             while (!que.empty()) {
     82                 int e = que.front();
     83                 que.pop();
     84                 vis[e] = false; 
     85                 for (int i = g.h[e], eu, w; ~i; i = g[i].nx) {
     86                     if (!g[i].r)
     87                         continue;
     88                     eu = g[i].ed, w = f[e] + g[i].c;
     89                     if (w > f[eu]) {
     90                         f[eu] = w, le[eu] = i, mf[eu] = min(mf[e], g[i].r);
     91                         if (!vis[eu]) {
     92                             vis[eu] = true;
     93                             que.push(eu);
     94                         }
     95                     }
     96                 }
     97             }
     98             if (f[T] == -inf)
     99                 return inf;
    100             int rt = 0;
    101             for (int p = T, e; ~le[p]; p = g[e ^ 1].ed) {
    102                 e = le[p];
    103                 g[e].r -= mf[T];
    104                 g[e ^ 1].r += mf[T];
    105                 rt += mf[T] * g[e].c;
    106             }
    107             return rt;
    108         }
    109 
    110         int max_cost() {
    111             int rt = 0, delta;
    112             while ((delta = spfa()) != inf) {
    113                 rt += delta;
    114 //                cerr << delta << '
    ';
    115             }
    116             return rt;
    117         }
    118 } Graph;
    119 
    120 int n, m, k;
    121 
    122 inline void solve() {
    123     scanf("%d%d%d", &n, &m, &k);
    124     Graph graph(0, n + 1);
    125     MapManager& g = graph.g;
    126     k = min(k, m);
    127     g = MapManager(n + 1);
    128     g.addArc(0, 1, k, 0);
    129     for (int i = 1, x; i <= n; i++) {
    130         scanf("%d", &x);
    131         g.addArc(i, min(n + 1, i + m), 1, x);
    132         g.addArc(i, i + 1, k, 0);
    133     }
    134     printf("%d
    ", graph.max_cost());
    135 }
    136 
    137 int main() {
    138     solve();
    139     return 0;
    140 }
  • 相关阅读:
    属性 Owner 不可用于 数据库...
    DHCP Client 服务无法启动,错误代码5:访问被拒绝
    删除域控中不活动的计算机
    在VMWare下LINUX中安装VMTool及共享文件夹
    ID 13508
    系统时间同步服务器地址收集
    windows 2003 登陆框 黑色解决办法
    linux下限制su权限
    linux screen + vim + taglist +ctags 使用
    gmail要求启用ActiveX控件,以及人人网没法分享的问题
  • 原文地址:https://www.cnblogs.com/yyf0309/p/10198124.html
Copyright © 2020-2023  润新知