Pagini recente » Cod sursa (job #18374) | Cod sursa (job #2061275) | Cod sursa (job #2891538) | Cod sursa (job #2479021) | Cod sursa (job #2884229)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
const int inf=1e9;
///dp[i][j]=numarul minim de obiecte necesare cu greutatea<= i pentru a obtine o greutate j
int N, G, f[205], dp[205][1005];
vector<int> sol;
pair<int,int> last[205][1005];
deque<pair<int,int>> dq[205];
int main()
{
fin>>N>>G;
int x;
for(int i=1;i<=N;i++){
fin>>x;
f[x]++;
}
int sum=0;
for(int i=200;i>=1 and G>1000;i--){
while(G>1000 and f[i]){
G-=i;
sum+=i;
f[i]--;
sol.push_back(i);
}
}
for(int i=0;i<=200;i++)
for(int j=1;j<=G;j++)
dp[i][j]=inf;
for(int i=1;i<=200;i++){
for(int j=0;j<=G;j++)
dp[i][j]=dp[i-1][j];
if(f[i]==0)
continue;
for(int j=0;j<i;j++)
dq[j].clear();
int nr=f[i];
for(int j=0;j<=G;j++){
int rest=j%i;
while(!dq[rest].empty() and dq[rest].back().first>=dp[i-1][j])
dq[rest].pop_back();
dq[rest].push_back({dp[i-1][j],j});
while(!dq[rest].empty() and (j-dq[rest].front().second)>nr*i)
dq[rest].pop_front();
if(dq[rest].front().first+(j-dq[rest].front().second)/i<dp[i][j]){
dp[i][j]=dq[rest].front().first+(j-dq[rest].front().second)/i;
last[i][j]={i,(j-dq[rest].front().second)/i};
}
}
}
while(G>=0){
if(dp[200][G]!=inf)
break;
G--;
}
int ind=200, ini=G;
while(G>0){
pair<int,int> t=last[ind][G];
ind--;
while(t.second--){
sol.push_back(t.first);
G-=t.first;
}
}
G=ini;
fout<<G+sum<<' '<<sol.size()<<'\n';
for(auto x : sol)
fout<<x<<'\n';
fin.close();
fout.close();
return 0;
}