Pagini recente » Cod sursa (job #1133259) | Cod sursa (job #1706584) | Cod sursa (job #2049847) | Cod sursa (job #3124987) | Cod sursa (job #2206976)
#include <bits/stdc++.h>
using namespace std;
int g,G[2][75000],N[2][75000];
short V[20000];
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
void dpi(int i_f,int i_s,int j_s,int g){
//cout<<"dpi:\n";
for (int i=i_s-1;i>=i_f;i--){
for (int j=j_s;j<=g-V[i];j++){
int p = j+V[i];
if(p<=g)
if(G[1][p]+V[i]>G[1][j] || (G[1][p]+V[i]==G[1][j] && N[1][p]+1<N[1][j])){
G[1][j]=G[1][p]+V[i];
N[1][j]=N[1][p]+1;
}
}
/*for(int j=j_s;j<=g;j++)
cout<<G[1][j]<<' ';
cout<<'\n';*/
}
}
void dp(int i_s,int i_f,int j_s,int g){
// cout<<"dp:\n";
for (int i=i_s;i<i_f;i++){
for (int j=g;j>=j_s;j--){
int p = j-V[i];
if (p>=j_s)
if(G[0][p]+V[i]>G[0][j] || (G[0][p]+V[i]==G[0][j] && N[0][p]+1<N[0][j])){
G[0][j]=G[0][p]+V[i];
N[0][j]=N[0][p]+1;
}
}
/* for(int j=j_s;j<=g;j++)
cout<<G[0][j]<<' ';
cout<<'\n';*/
}
}
void nul(int *p, int s,int f){
for(int i=s;i<=f;i++) p[i]=0;
}
bool first = true;
void solve(int s,int n, int j_s,int g){
if (n-s == 1 || n==s){
if(V[s]<=g-j_s) fout<<V[s]<<'\n';
} else if(n>s && j_s<=g){
//Initializarea tuturor datelor(tabelele si mijlocul)
nul(G[0],j_s,g);
nul(G[1],j_s,g);
nul(N[0],j_s,g);
nul(N[1],j_s,g);
int m = (n-s)/2 + s;
//Parcurgerea si rezolvarea cu ajutorul dp a tablourilor
dp(s,m,j_s,g);
dpi(m,n,j_s,g);
//Sumarea celor doua linii de tabel si cautarea celui mai optim rezultat ce se va afla pe indicele imax
int mx=0,nmin=0,imax=0;
// cout<<"sum: ";
for(int i=j_s;i<=g;i++){
G[0][i]+=G[1][i];
N[0][i]+=N[1][i];
// cout<<G[0][i]<<' ';
if(G[0][i]>mx||(G[0][i]==mx && N[0][i]<nmin)){
mx=G[0][i];
nmin=N[0][i];
imax=i;
}
}
// cout<<" imax = "<<imax<<'\n';
//In cazul in care rezultatul e gasit prima oara atunci scriem tot in fisier
if (first){
//cout<<mx<<' '<<nmin<<'\n';
fout<<mx<<' '<<nmin<<'\n';
first=false;
}
//"Feliem" tabelul in 4 si prelucram coltul de dreapta-sus si stanga-jos
if (mx){
solve(s,m,j_s,imax);
solve(m,n,imax,g);
}
}
}
int main(){
int n;
fin>>n>>g;
for (int i=0;i<n;i++)
fin>>V[i];
solve(0,n,0,g);
// dp(0,n,0,g);
return 0;
}