BZOJ1168 [Baltic2008]Gloves

来源:互联网 发布:惠阳区网络问政平台 编辑:程序博客网 时间:2024/06/08 03:47

发现我根本做不动ahcisy做的题啊……

orz了一发ahcisy题解

首先把有一个抽屉里没有这种种类的都刨出去然后直接计算

那么考虑每种都是两个抽屉里都有的情况

最劣情况肯定是把所有种类分成两个集合,第一个集合里共有p个,第二个集合里共有q个,第一个抽屉里拿的就是这p个,第二个里拿的就是那q个

那么所有x<=p,y<=q的就都不合法

那么枚举2^n种分法,搞一发单调栈就行了

#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 21#define MAXM 1100010#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000struct data{int v[2];friend bool operator <(data x,data y){return x.v[0]!=y.v[0]?x.v[0]<y.v[0]:x.v[1]>y.v[1];}};int n,tot;int a[2][MAXN];int ad[2];data c[MAXM];data st[MAXM];int tp;int ansv=2000000000,ans1=2000000000,ans2=2000000000;void ud(int x,int y){if(x+y<ansv||(x+y==ansv&&x<ans1)){ansv=x+y;ans1=x;ans2=y;}}int main(){int i,j;scanf("%d",&n);for(i=0;i<2;i++){for(j=0;j<n;j++){scanf("%d",&a[i][j]);}}for(i=0;i<n;i++){if(!a[0][i]||!a[1][i]){ad[0]+=a[0][i];ad[1]+=a[1][i];}else{a[0][tot]=a[0][i];a[1][tot++]=a[1][i];}}n=tot;int N=1<<n;for(i=0;i<N;i++){for(j=0;j<n;j++){c[i].v[i>>j&1]+=a[i>>j&1][j];}}ud(c[0].v[0],1);ud(1,c[N-1].v[1]);sort(c,c+N);for(i=0;i<N;i++){while(tp&&st[tp].v[1]<c[i].v[1]){tp--;}st[++tp]=c[i];}for(i=2;i<=tp;i++){ud(st[i-1].v[0]+1,st[i].v[1]+1);}printf("%d %d\n",ans1+ad[0],ans2+ad[1]);return 0;}/**/


0 0
原创粉丝点击