zoukankan      html  css  js  c++  java
  • bzoj 1283: 序列

    1283: 序列

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 486  Solved: 280
    [Submit][Status][Discuss]

    Description

    给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为M的子串中被选出的元素不超过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<=100。Ci<=20000。

        一个非常经典的网络流问题,题目要求的 每个相邻的k个数中不能选超过M个相当于    从n个数中选k次,且每次选的数两两直接距离>M。

        然后我们就 从 i -> i+1 容量 inf 费用 0,表示不选; 从i -> min(i+M,T) 容量 1 费用 0,表示某一轮选这个数;再连 S->1 容量 k 费用 0.

        这样最大费用最大流就是答案了。

    #include<bits/stdc++.h>
    #define ll long long
    #define pb push_back
    using namespace std;
    const int maxn=1005;
    const int inf=1e9;
    vector<int> g[maxn];
    struct lines{
    	int from,to,flow,cap,cost;
    }l[maxn*200];
    int S,T,t=-1,A[maxn],d[maxn];
    int n,m,k,a[maxn],ans,p[maxn];
    bool iq[maxn];
    
    inline void add(int from,int to,int cap,int cost){
    	l[++t]=(lines){from,to,0,cap,cost},g[from].pb(t);
    	l[++t]=(lines){to,from,0,0,-cost},g[to].pb(t);
    }
    
    inline bool SPFA(){
    	memset(d,-0x3f,sizeof(d)); queue<int> q;
    	q.push(S),d[S]=0,iq[S]=1,p[S]=0,A[S]=inf;
    	int x; lines e;
    	
    	while(!q.empty()){
    		x=q.front(),q.pop();
    		
    		for(int i=g[x].size()-1;i>=0;i--){
    			e=l[g[x][i]];
    			if(e.flow<e.cap&&d[x]+e.cost>d[e.to]){
    				d[e.to]=d[x]+e.cost;
    				A[e.to]=min(A[x],e.cap-e.flow);
    				p[e.to]=g[x][i];
    				if(!iq[e.to]) iq[e.to]=1,q.push(e.to);
    			}
    		}
    		
    		iq[x]=0;
    	}
    	
    	if(d[T]==d[T+1]) return 0;
    	ans+=d[T]*A[T];
    	
    	int now=T,pre;
    	while(now!=S){
    		pre=p[now];
    		l[pre].flow+=A[T];
    		l[pre^1].flow-=A[T];
    		now=l[pre].from;
    	}
    	
    	return 1;
    }
    
    inline void MFMC(){
    	while(SPFA());
    }
    
    int main(){
    	scanf("%d%d%d",&n,&m,&k),S=0,T=n+1;
    	for(int i=1;i<=n;i++) scanf("%d",a+i);
    	add(S,1,k,0);
    	for(int i=1;i<=n;i++) add(i,i+1,inf,0),add(i,min(i+m,T),1,a[i]);
    	MFMC(),printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    关于抽象类
    封装.继承.多态
    构造方法
    String
    无参方法与有参方法
    类和对象
    使用分层实现业务处理(二)
    使用分层实现业务处理(一)
    序列化Serializable接口
    用JSP从数据库中读取图片并显示在网页上
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8875757.html
Copyright © 2011-2022 走看看