제출 #1367020

#제출 시각아이디문제언어결과실행 시간메모리
1367020ivazivaKitchen (BOI19_kitchen)C++20
72 / 100
1095 ms16196 KiB
#include <bits/stdc++.h>

using namespace std;

#define MAXN 301
#define MAXM 45
#define int long long

int n,m,k;
int a[MAXN],b[MAXN];
int number[MAXN];
queue<int> q;
bool dp[MAXN*MAXN];
bool newdp[MAXN][MAXN*MAXN];
vector<int> grt;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>m>>k;
	for (int i=1;i<=n;i++) cin>>a[i];
	for (int i=1;i<=m;i++) cin>>b[i];
	int suma=0;for (int i=1;i<=n;i++) suma+=a[i];
	if (m<=15)
	{
		/// proslo za 31 poen
		int answer=INT_MAX;
		for (int maska=0;maska<(1<<m);maska++)
		{
			int sumb=0;for (int i=1;i<=n;i++) {number[i]=0;q.push(i);}
			for (int bit=0;bit<m;bit++)
			{
				if (!(maska&(1<<bit))) continue;
				sumb+=b[bit+1];
				for (int num=1;num<=min(n,b[bit+1]);num++) 
				{
					if (q.empty()) break;
					int node=q.front();q.pop();
					number[node]++;
					if (number[node]<a[node]) q.push(node);
				}
			}
			while (!q.empty()) q.pop();
			bool valid=true;
			for (int node=1;node<=n;node++)
			{
				if (number[node]<k) {valid=false;break;}
			}
			if (valid==true and sumb>=suma) answer=min(answer,sumb-suma);
		}
		if (answer==INT_MAX) {cout<<"Impossible"<<endl;return 0;}
		else {cout<<answer<<endl;return 0;}
	}
	if (k==1)
	{
		/// proslo za 20 poena
		dp[0]=true;for (int i=1;i<MAXN*MAXN;i++) dp[i]=false;
		for (int i=1;i<=m;i++)
		{
			for (int val=MAXN*MAXN-1;val>=0;val--)
			{
				if (val+b[i]>=MAXN*MAXN) continue;
				if (dp[val]) dp[val+b[i]]=true;
			}
		}
		int answer=INT_MAX;
		for (int val=suma;val<MAXN*MAXN;val++)
		{
			if (dp[val]) {answer=val-suma;break;}
		}
		if (answer==INT_MAX) {cout<<"Impossible"<<endl;return 0;}
		else {cout<<answer<<endl;return 0;}
	}
	bool subtask4=true;
	/*
	if (n>40) subtask4=false;
	if (m>40) subtask4=false;
	if (k>40) subtask4=false;
	for (int i=1;i<=n;i++)
	{
		if (a[i]>40) subtask4=false;
	}
	for (int i=1;i<=m;i++)
	{
		if (b[i]>40) subtask4=false;
	}
	*/
	if (subtask4)
	{
		for (int i=1;i<=n;i++)
		{
			if (a[i]<k) {cout<<"Impossible"<<endl;return 0;}
		}
		grt.push_back(0);int sumb=0;for (int i=1;i<=m;i++) sumb+=b[i];
		dp[0]=true;for (int val=1;val<=sumb;val++) dp[val]=false;
		for (int i=1;i<=m;i++)
		{
			if (b[i]>=n) {grt.push_back(b[i]);continue;}
			for (int val=sumb;val>=0;val--)
			{
				if (val+b[i]>=MAXN*MAXN) continue;
				if (dp[val]==true) dp[val+b[i]]=true;
			}
		}
		for (int number=0;number<(int)grt.size();number++)
		{
			for (int val=0;val<=sumb;val++) newdp[number][val]=false;
		}
		newdp[0][0]=true;
		for (int pos=1;pos<(int)grt.size();pos++)
		{
			for (int number=(int)grt.size()-1;number>=1;number--)
			{
				for (int val=sumb;val>=0;val--)
				{
					if (val+grt[pos]>=MAXN*MAXN) continue;
					if (newdp[number-1][val]==true) newdp[number][val+grt[pos]]=true;
				}
			}
		}
		int answer=INT_MAX;
		for (int val=0;val<=sumb;val++)
		{
			if (dp[val]==false) continue;
			int num_greater=k-val/n;
			if (num_greater<0) num_greater=0;
			else if (num_greater>=(int)grt.size()) continue;
			int fali=max((long long)0,suma-val);
			for (int value=fali;value<=min(sumb,suma+answer-1-val);value++)
			{
				bool indicator=false;
				for (int broj=num_greater;broj<(int)grt.size();broj++)
				{
					if (newdp[broj][value]==true) {answer=min(answer,val+value-suma);indicator=true;break;}
				}
				if (indicator) break;
			}
		}
		if (answer==INT_MAX) cout<<"Impossible"<<endl;
		else cout<<answer<<endl;
		return 0;
    }
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…