BZOJ 1531: [POI2005]Bank notes

按余数分类

单调队列优化

#include<cstdio>
using namespace std;
int n,m,b[205],c[205],F[20005];
struct node{
	int fr,sc;
}q[20005];
int main(){
	scanf("%d",&n);
	for (int i=1; i<=n; i++) scanf("%d",&b[i]);
	for (int i=1; i<=n; i++) scanf("%d",&c[i]);
	scanf("%d",&m);
	for (int i=1; i<=20000; i++) F[i]=1e9;
	for (int i=1; i<=n; i++){
		for (int d=0; d<b[i]; d++){
			int head=1,tail=0;
			for (int j=0; b[i]*j+d<=m; j++){
				int now=b[i]*j+d;
				while (head<=tail && q[tail].sc>=F[now]-j) tail--;
				q[++tail]=(node){j,F[now]-j};
				while (head<=tail && q[head].fr<j-c[i]) head++;
				F[now]=1e9;
				if (head<=tail) F[now]=q[head].sc+j;
			}
		}
	}
	printf("%d\n",F[m]);
	return 0;
}

  

posted @ 2018-11-06 18:44  ~Silent  阅读(157)  评论(0编辑  收藏  举报
Live2D