1. 程式人生 > >NKOJ P3802 不死【狀態壓縮】【二分答案】

NKOJ P3802 不死【狀態壓縮】【二分答案】

二分答案即可,狀壓是比較普通的狀態:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e5+5;
const ll Inf=1e18;

ll f[N][1<<6];
ll n,t=63,st,cla[N],sle[N],uns[N];

ll ans;

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

bool check(ll x) {
	rep(i,0,n) rep(j,0,t) f[i][j]=Inf;f[0][0]=st;
	
	rep(i,1,n) rep(j,0,t) {
		if(cla[i]==7) {
			if(f[i-1][j]<=x) f[i][j]=f[i-1][j]-sle[i];
		} else {
			ll k=1<<(cla[i]-1);
			if(j&k) {
				if(f[i-1][j^k]<=x) f[i][j]=f[i-1][j^k]-sle[i];
			} else {
				if(f[i-1][j]<=x) f[i][j]=min(f[i][j],f[i-1][j]+uns[i]);
				if(f[i-1][j^k]<=x) f[i][j]=min(f[i][j],f[i-1][j^k]+uns[i]);
			}
		}
	}
	
	rep(i,0,t) if(f[n][i]<=x) return true;
	
	return false;
}

int main() {
	n=read();
	
	rep(i,1,n) cla[i]=read();
	
	rep(i,1,n) sle[i]=read();
	
	rep(i,1,n) uns[i]=read();st=read();
	
	ll l=st,r=Inf;
	while(l<=r) {
		ll mid=l+r>>1;
		if(check(mid)) r=mid-1;
		else l=mid+1;
	}
	
	printf("%lld",l);
	
	return 0;
}