Submission #517122

#TimeUsernameProblemLanguageResultExecution timeMemory
517122truongxuan_dhKnapsack (NOI18_knapsack)C++14
100 / 100
230 ms4512 KiB
//#pragma GCC optimize(3)
#define NDEBUG
#include <bits/stdc++.h>
using namespace std;
struct item{
	long long value;
	int weight;
	long long copies;
};
pair<long long,int> pseudoitems[3000000];
pair<long long,int> *pi_end; // value, weight
item items[100000];
item *items_end;
long long gcd(long long a, long long b){
    if(a==0)return b;
    if(b==0)return a;
    return gcd(b,a%b);
}
int main(){
	ios_base::sync_with_stdio(false);
	//cin.tie(nullptr);
	//cout.tie(nullptr);
	int s,n;
	while(cin>>s>>n&&s){
		assert(s>=1&&s<=2000);
		assert(n>=1&&n<=100000);
		pi_end=pseudoitems;
		for(int i=0;i<n;++i){
            cin>>items[i].value>>items[i].weight>>items[i].copies;
            assert(items[i].value>=1&&items[i].value<=1000000);
            assert(items[i].weight>=1&&items[i].weight<=s);
            assert(items[i].copies>=1&&items[i].copies<=1000000000);
            /*int x=(int)gcd(items[i].value,items[i].weight);
            items[i].value/=x;
            items[i].weight/=x;
            items[i].copies*=x;*/
		}
		sort(items,items+n,[](const item& a, const item& b){
		    if(b.weight==a.weight)return a.value>b.value;
		    return a.weight<b.weight;
		});
		items_end=items+n;
		/*items_end=remove_if(items,items+n,[](const item& itm){
		    //return itm.value<30;
		    return itm.value/itm.weight<4000;
		});*/
		auto it=items+1;
		auto it_end=items_end;
		items_end=items;
		int ct=0;
		//cout<<"test"<<endl;
		for(;it!=it_end;++it){
            item itm=*it;
            if(itm.weight==items_end->weight){
                if(ct>s/itm.weight);//items_end->copies+=itm.copies;
                else *(++items_end)=itm;
                ++ct;
                //items_end->value=max(items_end->value,it->value);
            }
            else{
                *(++items_end)=itm;
                ct=0;
            }
		}
		//cout<<"test"<<endl;
		++items_end;
		for(auto it=items;it!=items_end;++it){
			const item& itm=*it;
			int p;
			for(p=0;(1ll<<(p+1))<=itm.copies;++p){
				if((long long)itm.weight*(1ll<<p)<=s){
					*pi_end++=make_pair(itm.value*(1ll<<p),itm.weight*(1ll<<p));
				}
			}
			long long cp=itm.copies-((1ll<<p)-1);
			if((long long)itm.weight*cp<=s){
				*pi_end++=make_pair(itm.value*cp,itm.weight*cp);
			}
		}
		//cout<<"test"<<endl;
		long long* prev=new long long[s+1];
		fill_n(prev,s+1,0);
		for(auto it=pseudoitems;it!=pi_end;++it){
			long long* curr = new long long[s+1];
			for(int j=0;j<=s;++j){
				curr[j]=prev[j];
				if(j+it->second<=s){
					curr[j]=max(curr[j],prev[j+it->second]+it->first);
				}
			}
			delete[] prev;
			prev=curr;
		}
		//cout<<"test"<<endl;
		cout<<prev[0]<<'\n';
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...