Cod sursa(job #2335535)

Utilizator patcasrarespatcas rares danut patcasrares Data 4 februarie 2019 11:35:12
Problema Ghiozdan Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.85 kb
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
const int DB=22,DM=75002,DN=205;
int n,G,fr[DN],f;
int dp[2][DB][DM],ls,ld,poz,r1,r2;
int d[DM];
deque<int>z;
void solve2(int h,int &G,int t)
{
	if(h==0)
		return;
	for(int i=1;i<=dp[1][h][G];i++)
		z.push_front(h+t);
	G-=dp[1][h][G]*(h+t);
	solve2(h-1,G,t);
}
void solve(int G,int type,int B)
{
	if(G==0)
		return;
	for(int i=0;i<DM;i++)
	{
		dp[0][0][i]=1e9;
		dp[1][0][i]=0;
	}
	dp[0][0][0]=0;
	dp[1][0][0]=0;
	for(int h=1;h<=B;h++)
	{
		ls=1;
		ld=0;
		poz=h;
		poz%=20;
		if(poz==0)
			poz=20;
		for(int rest=0;rest<h;rest++)
		{
			ls=1;
			ld=0;
			for(int i=rest;i<DM;i+=h)
			{
				dp[1][poz][i]=0;
				dp[0][poz][i]=dp[0][poz-1][i];

				while(1)
				{
					if(ls>ld)
						break;
					if((i-d[ls])/h<=fr[h])
						break;
					ls++;
				}
				if(ls<=ld)
				{
					//cout<<h<<' '<<i<<' '<<ls<<' '<<ld<<'\n';
					if(dp[0][poz-1][d[ls]]+(i-d[ls])/h<dp[0][poz][i])
					{
						dp[0][poz][i]=dp[0][poz-1][d[ls]]+(i-d[ls])/h;
						dp[1][poz][i]=(i-d[ls])/h;
						//cout<<i<<' '<<dp[1][poz][i]<<'\n';
					}
				}
				while(1)
				{
					if(ls>ld)
						break;
					if(dp[0][poz-1][i]>dp[0][poz-1][d[ld]]+(i-d[ld])/h)
						break;
					ld--;
				}
				ld++;
				d[ld]=i;
			}
		}
		if(poz==20)
		for(int i=0;i<DM;i++)
			dp[0][0][i]=dp[0][20][i];
	}
	if(type==0)
	{
		for(int i=G;i>=0;i--)
			if(dp[0][20][i]!=1e9)
			{
				r1=i;
				r2=dp[0][20][i];
				break;
			}
		fout<<r1<<' '<<r2<<'\n';
		G=r1;
	}
	solve2(20,G,B-20);
	//cout<<G<<'\n';
	solve(G,1,B-20);
}
int main()
{
	fin>>n>>G;
	for(int i=1;i<=n;i++)
	{
		fin>>f;
		fr[f]++;
	}
	if(G==0)
	{
		fout<<0<<' '<<0;
		return 0;
	}
	solve(G,0,200);
	for(auto i:z)
		fout<<i<<'\n';
}