bzoj3550: [ONTAK2010]Vacation&&1283: 序列

给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为 的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大。

据说是什么经典区间带权限制问题

有两种写法...

1.可以根据流量平衡列方程,然后添加一个变量将不等式化成等式。具体看NOI2008的志愿者招募。 
2.直接每个点依次排开,i->i+1连(k,0)【k是流量限制,0是费用】的边,然后对于一个区间[l,r]就l->r连(1,val);然后源点->1连(k,0),n->T一样,跑一边最大费用最大流即可。经过每个点的流量都保证了不超过k

#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
const int N=10240,inf=214748364;
struct Edge{
    int to,next,from,c,w;
}e[1000000];
int head[N],tot=1,ans,dis[N],from[N],m,K,n,T,x;
bool used[N];
inline void ins(int u,int v,int w,int cost) {
     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; e[tot].c=cost; e[tot].from=u;
}
inline bool spfa() {
     queue<int> q; rep(i,0,T) dis[i]=-1,from[i]=0,used[i]=0; dis[0]=1; q.push(0); used[0]=1;
     while(!q.empty()) {
          int x=q.front(); q.pop();
          used[x]=0;
          for(int k=head[x];k;k=e[k].next)
           if(e[k].w>0&&dis[x]+e[k].c>dis[e[k].to]){
                  dis[e[k].to]=dis[x]+e[k].c; from[e[k].to]=k;
                  if(!used[e[k].to]) {
                        used[e[k].to]=1; q.push(e[k].to);
                  }
            }
     }
     return dis[T]!=-1;
}
inline void run(){
     int x=inf;
     for(int k=from[T];k;k=from[e[k].from]) x=min(x,e[k].w);
     for(int k=from[T];k;k=from[e[k].from]) {
          e[k].w-=x; e[k^1].w+=x; ans+=e[k].c*x;
     }
}
inline void insert(int u,int v,int w,int c){
    ins(u,v,w,c); ins(v,u,0,-c);
}
int main(){
    scanf("%d%d",&m,&K); n=m*3;
    T=n+1;
    rep(i,1,n) {
        scanf("%d",&x);
        insert(i-1,i,K,0);
        if(i+m<=n) insert(i,i+m,1,x);else insert(i,T,1,x);
    }
    insert(n,T,K,0);
    while(spfa()) run();
    printf("%d\n",ans);
}

时间: 2024-10-10 23:42:10

bzoj3550: [ONTAK2010]Vacation&&1283: 序列的相关文章

BZOJ3550: [ONTAK2010]Vacation

3550: [ONTAK2010]Vacation Time Limit: 10 Sec  Memory Limit: 96 MBSubmit: 91  Solved: 71[Submit][Status] Description 有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个,其次要保证选出的数的个数最大. Input 第一行两个整数N,K.第二行有3N个整数. Output 一行一个整数表示答案. Sample Input 5 3 14 21 9 30 11

bzoj3550: [ONTAK2010]Vacation&amp;&amp;bzoj3112: [Zjoi2013]防守战线

学了下单纯形法解线性规划 看起来好像并不是特别难,第二个code有注释.我还有...*=-....这个不是特别懂 第一个是正常的,第二个是解对偶问题的 #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const double e

BZOJ 1283: 序列

1283: 序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 272  Solved: 151[Submit][Status][Discuss] Description 给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为 的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大. Input 第1行三个数N,m,k. 接下来N行,每行一个字符串表示Ci. Output 最大和. Sample Input

【BZOJ1283/3550】序列/[ONTAK2010]Vacation 最大费用流

[BZOJ1283]序列 Description 给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为 的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大. Input 第1行三个数N,m,k. 接下来N行,每行一个字符串表示Ci. Output 最大和. Sample Input 10 5 3 4 4 4 6 6 6 6 6 4 4 Sample Output 30 HINT 20%的数据:n<=10.100%的数据:N<=1000,k,m&

BZOJ 1283 序列 费用流 网络流 线性规划

https://darkbzoj.cf/problem/1283 给出一个长度为N的正整数序列Ci,求一个子序列,使得原序列中任意长度为M的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大. http://www.cnblogs.com/137shoebills/p/8871648.html ↑和这道题一样 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #i

BZOJ 1283 序列 费用流

题目大意:给定一个长度为n的序列,要求选一些数,使得任意一个长度为m个区间中最多选k个数,求最大的和 费用流直接跑就是了 把这个序列用流量为k费用为0的边连成一条直线 然后第i个点向第i+m个点连一条费用为a[i]流量为1的边 跑最大费用最大流即可 卡单纯型差评.... #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010 #d

BZOJ 3550 ONTAK2010 Vacation 单纯形

题目大意:给定一个长度为3n的区间,要求选一些数,且任意一段长度为n的区间内最多选k个数,求选择数的和的最大值 单纯形直接搞 注意一个数只能被选一次 因此要加上xi<=1这个约束条件 不明白3n还有k<=10是为何... #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define EPS 1

BZOJ 3550 [ONTAK2010]Vacation 线性规划

题意:链接 方法:线性规划 解析: 这是一道蛮简单的单纯性线性规划. 首先我们设Xi表示第i个数是否选择. 则显然 X1+X2+...+Xn<=k X2+X3...+Xn+1<=k - X2n+1+X2n+2+...+X3n<=k 其次0<=Xi<=1 并且我们要最大化∑3ni=1Ci?Xi 观察如上式子,显然为标准型线性规划. 单纯性出解即OK. 代码: #include <cstdio> #include <cstring> #include &l

[NetworkFlow]网络流建模相关

流 网络流问题本质上是线性规划问题的应用之一,线性规划问题的标准形式是给出一组等式约束和不等式约束,要求最优化一个线性函数. 在流问题中,变量以流量的形式出现在问题中,我们给出一个流网络(以有向图的形式)来解决有关流的问题. 流是整个网络流问题的核心所在,它实际上是定义在流网络上的一个线性函数,在流网络中,每条边都有一个流量f(u,v),流f=∑v∈Vf(S,v) 流量f(u,v)是流问题中的变量,它有两个约束,一个是不等式,一个是等式 (1)容量限制:f(u,v)≤c(u,v) (2)流量平衡