CF802C
题解
这是一个只需要
如何想到
首先,容易想到的是:如果不能卖出再买入,对于一个颜色
上图,数轴上每个点表示一天,每天的书都可以直接流向下一天,容量为
问题是,如何考虑卖出后再买入的操作呢?
仔细想,对于相邻两个
为什么是对的
这样做是对的吗?我们发现:如果这样做不是错的话那它一定是对的(。我们考虑到错的情况有两种:一个流流过了它不该流的边或者不该流入的汇点。
1.我们称相邻两个
2.假如
而且它情况实际上都可以转化成上述情况的。
实现
有一个小细节,如果你完全按照上述建图,会有一个问题: 如果一个点刚买就卖了,他是不会走书架边的,但实际上它当天需要占用一个书架位置。那我们换一种思路,我们认为这本书是前一天下班的时候买的,把入边连到上一天即可。
int main()
{
memset(head,-1,sizeof(head)); num_edge=-1;
N=read(), K=read();
for(int i=1; i<=N; i++) A[i]=read();
for(int i=1; i<=N; i++) C[i]=read();
s=N+1, t=N+2;
for(int i=1; i<N; i++) addEdge(i, i+1, K, 0);
for(int i=1; i<=N; i++){
if(!VIS[A[i]]) {
if(i == 1) addEdge(N+1, i, 1, C[A[i]]);
else addEdge(N+1, i-1, 1, C[A[i]]);
}else{
addEdge(VIS[A[i]], i-1, 1, C[A[i]]);
}
VIS[A[i]] = i;
}
for(int i=1; i<=N; i++) if(VIS[i]) addEdge(VIS[i], N+2, 1, 0);
MCMF();
printf("%d\n", mincost);
return 0;
}