码迷,mamicode.com
首页 > 其他好文 > 详细

3.2 模拟赛

时间:2019-03-02 21:10:37      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:style   alt   int   for   区间   string   模拟   printf   har   

T1 perform

题目大意:

一个序列,每个数可以取两种值$a_i$或$b_i$,要求任意连续的$k$个数中至少有$p$个数取$a$,$q$个数去取$b$

思路:

对于每个数先假设全取$b$ 则每个点被变成a之后会对一些区间影响

从最早的包含它的区间到最早不包含它的区间连边表示被流掉了

其余的点每个点向后连$k-p-q$以限制流量

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #define ll long long
12 #define inf 2139062143
13 #define MAXN 300
14 #define MAXM 1010
15 #define MOD 998244353
16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
18 #define ren for(register int i=fst[x];i;i=nxt[i])
19 #define pb(i,x) vec[i].push_back(x)
20 #define pls(a,b) (a+b)%MOD
21 #define mns(a,b) (a-b+MOD)%MOD
22 #define mul(a,b) (1LL*(a)*(b))%MOD
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
28     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
29     return x*f;
30 }
31 int n,S,T,k,p,q,ans;
32 struct ZKW
33 {
34     int fst[MAXN],to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1],cos[MAXM<<1],cnt;
35     int dis[MAXN],vis[MAXN],ret,q[MAXN<<4],l,r;
36     ZKW() {memset(fst,0,sizeof(fst));memset(vis,0,sizeof(vis));ret=0,cnt=1;}
37     void add(int u,int v,int w,int c) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w,cos[cnt]=c;}
38     void ins(int u,int v,int w,int c) {add(u,v,w,c);add(v,u,0,-c);}
39     int spfa()
40     {
41         rep(i,1,T) dis[i]=-inf,vis[i]=0;
42         dis[T]=0,vis[T]=1,q[l=r=1]=T;
43         while(l<=r)
44         {
45             int x=q[l++];vis[x]=0;
46             for(int i=fst[x];i;i=nxt[i])
47                 if(val[i^1]&&dis[to[i]]<dis[x]-cos[i])
48                 {
49                     dis[to[i]]=dis[x]-cos[i];
50                     if(!vis[to[i]]) vis[to[i]]=1,q[++r]=to[i];
51                 }
52         }
53         return dis[S]!=-inf;
54     }
55     int dfs(int x,int a)
56     {
57         if(x==T||!a) {ret+=dis[S]*a;return a;}
58         if(vis[x])return 0;
59         vis[x]=1;
60         int res=0,f;
61         for(int i=fst[x];i&&a;i=nxt[i])
62             if(dis[to[i]]==dis[x]-cos[i]&&(f=dfs(to[i],min(a,val[i]))))
63                 res+=f,val[i]-=f,val[i^1]+=f,a-=f;
64         return res;
65     }
66     int solve(int f=0)
67     {
68         while(spfa()) f+=dfs(S,inf);return f;
69     }
70 }Z;
71 int main()
72 {
73     freopen("perform.in","r",stdin);
74     freopen("perform.out","w",stdout);
75     n=read(),k=read(),p=read(),q=read(),S=n+2,T=n+3;int a,b,l,r;
76     rep(i,1,n)
77     {
78         a=read(),b=read(),ans+=b,a-=b;
79         r= i+k<=n?i+k:T;Z.ins(i,r,1,a);
80     }
81     Z.ins(S,n+1,k-q,0);Z.ins(n,T,k-p-q,0);
82     rep(i,1,k) Z.ins(n+1,i,1,0);rep(i,1,n-1) Z.ins(i,i+1,k-p-q,0);
83     Z.solve();printf("%d\n",ans+Z.ret);
84 }
View Code

 

3.2 模拟赛

标签:style   alt   int   for   区间   string   模拟   printf   har   

原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10461370.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!