Pagini recente » Cod sursa (job #1611326) | Cod sursa (job #301745) | Cod sursa (job #1091027) | Cod sursa (job #3222251) | Cod sursa (job #393515)
Cod sursa(job #393515)
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define PB push_back
#define GM 75005
#define inf 2000000000
int N,G,gmax;
int CATE[201];
int B[GM][15],R[GM][15][2],A[GM][2];
int IND[201];
vector<int> V;
int main()
{
int g;
freopen("ghiozdan.in","r",stdin);
freopen("ghiozdan.out","w",stdout);
scanf("%d %d",&N,&G);
int sq=(int)sqrt(N);
for(int i=1;i<=N;++i)
{
scanf("%d",&g);
gmax=max(gmax,g);
if(!CATE[g]) V.PB(g);
++CATE[g];
}
V.PB(0);
sort(V.begin(),V.end());
int dim=0;
for(int i=1;i<=G;++i)
{
A[i][0]=inf;
B[i][0]=inf;
}
for(int i=1;i<V.size();++i)
{
int cur=i%2;
int prev=!cur;
int cat=V[i];
for(int j=0;j<=G;++j)
A[j][cur]=inf;
for(int j=0;j<cat;++j)
{
int st=0,dr=-1;
for(int k=0;k*cat+j<=G;++k)
{
//scoateri
while((st<=dr) && (k*cat+j-IND[st])>CATE[cat]*cat) ++st;
//inserari
int val_cur=A[k*cat+j][prev];
if(val_cur!=inf)
{
while((st<=dr) && (val_cur<=A[IND[dr]][prev]+(k*cat+j-IND[dr])/cat)) --dr;
++dr;
IND[dr]=k*cat+j;
}
if(st<=dr) A[k*cat+j][cur]=A[IND[st]][prev]+(k*cat+j-IND[st])/cat;
else A[k*cat+j][cur]=inf;
}
}
/*
for(int j=0;j<=G;++j)
printf("%d ",A[j][cur]);
printf("\n");
*/
}
int i=G;
while(A[i][(V.size()-1)%2]==inf) --i;
printf("%d %d",i,A[i][(V.size()-1)%2]);
return 0;
}