[bzoj3550][单纯形][线性规划][ONTAK2010]Vacation

xiaoxiao2021-02-28  72

3550: [ONTAK2010]Vacation

Time Limit: 10 Sec Memory Limit: 96 MB Submit: 310 Solved: 222 [Submit][Status][Discuss] Description

有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个,其次要保证选出的数的个数最大。

Input

第一行两个整数N,K。 第二行有3N个整数。

Output

一行一个整数表示答案。

Sample Input

5 3

14 21 9 30 11 8 1 20 29 23 17 27 7 8 35

Sample Output

195

HINT

【数据范围】

N<=200,K<=10。

Source

By Sbullet

sol: 单纯形,注意一下这里要限制每个点只能选一次。

#include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> using namespace std; int n,m,M; inline int read() { char c; int res,flag=0; while((c=getchar())>'9'||c<'0') if(c=='-')flag=1; res=c-'0'; while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0'; return flag?-res:res; } const int N=1110; const double eps=1e-8; int l,e; double a[N][N],b[N],c[N]; double v; inline void pivot() { b[l]/=a[l][e]; for(int i=1;i<=m;++i) if(i!=e) a[i][e]/=a[l][e]; a[l][e]=1/a[l][e]; for(int i=1;i<=M;++i) if(fabs(a[i][e])>eps&&i!=l) { b[i]-=b[l]*a[i][e]; for(int j=1;j<=m;++j) if(j!=e) a[i][j]-=a[l][j]*a[i][e]; a[i][e]*=-a[l][e]; } v+=c[e]*b[l]; for(int i=1;i<=m;++i) if(i!=e) c[i]-=c[e]*a[l][i]; c[e]*=-a[l][e]; } inline double simplex() { while(true) { l=0;e=0; for(e=1;e<=m;++e) if(c[e]>eps) break; if(e==m+1) return v; double save=1e9; for(int i=1;i<=M;++i) if(a[i][e]>eps&&save>b[i]/a[i][e]) save=b[i]/a[i][e],l=i; // if(save==1e9) return 1e9; pivot(); } } int main() { // freopen("3550.in","r",stdin); // freopen(".out","w",stdout); n=read(); m=n*3; int k=read(); for(int i=1;i<=m;++i) c[i]=read(); for(int i=n*2+1;i>=1;--i) { b[i]=k; for(int j=1;j<=n;++j) if(i+j-1>m) break; else a[i][i+j-1]=1; } M=n*2+1; for(int i=1;i<=m;++i) { ++M; b[M]=1; a[M][i]=1; } printf("%d",(int)(simplex()+0.5)); }
转载请注明原文地址: https://www.6miu.com/read-96281.html

最新回复(0)