Submission #1330215

#TimeUsernameProblemLanguageResultExecution timeMemory
1330215sudama_beraKnapsack (NOI18_knapsack)C++20
37 / 100
1096 ms29460 KiB
#include <bits/stdc++.h>
using namespace std;
//policy based data structure
#include<bits/extc++.h>
using namespace __gnu_pbds;
using pii=pair<int,int>;
typedef tree<
 pii,
 null_type,
 less<pii>,
 rb_tree_tag,
 tree_order_statistics_node_update
>ordered_set;
// os.find_by_order(k); iterator kth lowest element
// os.order_of_key(x);  number of elements strictly less than x


// some bits operations
//x&(x-1) unsets the rightmost set bit
//x&(-x) isloates the rightmost set bit
//x-(x&-(-x)) removing the last set bit one by one 
//x-1 unsets the rightmost set bit and sets all the trailing zeros
// x=100100110000;
// x-1==100100101111
// x|(x-1) all the trailing zeros are set
// sum(a,b)=(a&b)+(a|b);
// sum(a,b)=(a^b)+2*(a&b);
// a^b is addition without the carry and a&b is the carry hence multiply by 2 to shift

// product of factors = n^(x/2) where x=number of factors



//ax+by=g
//ax+by=c

// let Xg and Yg be value got from ax+by=g using ext_gcd
// solution of ax+by=c [X0,Y0]=[Xg*c/g,Yg*c/g]
// a(x+b/g)+b(y-a/g)=c;
// X1=X0+k*(b/g) Y1=Y0-k*(a/g)

int gcd_ext(int a,int b,int&x,int&y){
   //base case
    if(b==0){
        x=1,y=0;
        return a;
    }
    int x1,y1;
    int g=gcd_ext(b,a%b,x1,y1);
    x=y1;
    y=x1-(a/b)*y1;
    return g;

}
//chinese reminder theroem
 // x==(a1%m1)
 // x==(a2%m2)
 // ...
//m1,m2,m3... are pairwise coprime
// let m=m1*m2*m3...
// then there exist exactly one x in [0,m-1] that satisfies the congrunecy
// x= a1*(m/m1)*inv(m/m1)%m1+a2*(m/m2)*inv(m/m2)%m2....

#define f first
#define s second
using ll=long long;
using ld=long double;
const long long inf=1e18+1;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
long long  M=998244353;
///M=k*a+r M is prime
// k=(M/a) r=M%a
// 0=(K*a+r)%M
// inv(a)%M=(M-inv(r)*(m/a))%M
long long exp(long long x,long long y){
    long long res=1;
    while(y){
      if(y&1){
        res=(res*x)%M;
      }
      y=y>>1;
      x=(x*x)%M;
    }
    return res;
}
long long dist(int xi,int yi,int xj,int yj){
    return (xi-xj)*1ll*(xi-xj)+(yi-yj)*1ll*(yi-yj);
}

class dsu{
public:
    vector<int>par;
    vector<int>size;
public:
    dsu(int n){
        par.resize(n);
        size.resize(n);
        for(int i=0;i<n;i++){
            par[i]=i;
            size[i]=1;
        }
    }
  int find(int u){
    if(u==par[u]){return u;}
    return par[u]=find(par[u]);
  }
  void unite(int u,int v){
    int par_u=find(u);
    int par_v=find(v);
    if(par_u==par_v){return;}
    // assumig par_u is smaller
    if(size[par_u]>size[par_v]){
       swap(par_u,par_v);
    }
    size[par_v]+=size[par_u];
    par[par_u]=par_v;
    return;
  }
  bool connected(int u,int v){
    return (find(u)==find(v));
  }

}; 
class fenwick{
    public: 
        vector<long long>bit;
        int n;
    fenwick(int n,vector<int>&a){
        this->n=n;
        bit.assign(n+1,0LL);
        for(int i=0;i<n;i++){
            bit[i+1]=a[i];
        }
        for(int i=1;i<=n;i++){
            int r=i+(i&(-i));
             if(r<=n)bit[r]+=bit[i];
        }
    }
    void update(int r,int val){
        int cur_r=r+1;
        while(cur_r<=n){
            bit[cur_r]+=val;
            cur_r=cur_r+(cur_r&(-cur_r));
        }
        return ;
    }
    long long sum(int r){
        int cur_r=r+1;
        long long ret_sum=0;
        while(cur_r>0){
            ret_sum+=bit[cur_r];
            cur_r=cur_r-(cur_r&(-cur_r));
        }
        return ret_sum;
    }
    long long sum_qry(int l,int r){
        return sum(r)-sum(l-1);
    }
};

class sgt{
public:
    vector<long long>t;
    sgt(int n){
        t.assign(4*n, 0);
    }
    void build(int tl,int tr,int v,vector<long long>&a){
        if(tl==tr){
            t[v]=a[tl];
            return;
        }
        int mid=(tl+tr)/2;
        build(tl,mid,v*2+1,a);
        build(mid+1,tr,v*2+2,a);
        t[v] =t[v*2+1]+t[v*2+2];
    }
    void update(int v,long long val,int pos,int tl,int tr){
        if(tl==tr){
            t[v]=val;
            return;
        }
        int mid = (tl + tr)/2;
        if(pos<=mid) update(v*2+1,val,pos,tl,mid);
        else update(v*2+2,val,pos,mid+1,tr);
        t[v]=t[v*2+1]+t[v*2+2];
    }
    long long query(int l,int r,int tl,int tr,int v){
        if(l>r) return 0;
        if(l==tl&&r==tr)return t[v];
        int mid=(tl+tr)/2;
        return query(l,min(r,mid),tl,mid,v*2+1)
             + query(max(l,mid+1),r,mid+1,tr,v*2+2);
    }
};
using ll =long long;
using pll=pair<long long,long long>;
using pii=pair<int,int>;
#define all(x) (x).begin(),(x).end()
#define all_rev(x) (x).rbegin(),(x).rend()
typedef vector<int> vi;
typedef vector<long long>vll;
#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
vector<vector<int>>g;
vector<vector<pii>>gwt;
vector<bool>vis;
vector<int>v;
std::vector<ll> pf;

const int mx=1e6+1;
// phi[i]=i*multiply(1-1/prime_factors)
//phi(i*j)=phi(i)*phi(j)*g/phi(g)
//(a^(n))%m==== (a^(n%phi(m)))%m
vector<int>phi(mx+1);
void cal_phi(){
    for(int i=0;i<=mx;i++){
        phi[i]=i;
    }
    for(int i=2;i<=mx;i++){
        if(phi[i]==i){
            for(int j=i;j<=mx;j=j+i){
                phi[j]=(phi[j])-(phi[j]/i);
            }
        }
    }
}
vector<bool>prime(mx,true),lpf(mx);
void seiv_algo(){
    prime[0]=prime[1]=false;
    for(int i=2;i<mx;i++){
        if(prime[i]){
            lpf[i]=i;
            for(int j=2*i;j<mx;j=j+i){
                prime[j]=false;
                if(lpf[j]==0)lpf[j]=i;
            }
        }
    }
}
ll mod_inv(ll x){
    return( M+exp(x,M-2))%M;
}
// number of dearrangement== n!(sum(-1^k/k!)) i.e n!(1/0!-1/1!+1/2!-1/3!...)
// let 1st person get ith hat
// then case1: i also get the 1st hat .... i can have n-1 values
//              then now there are n-2 hats to solve
//              giving as (n-1)*(f(n-2))
//     case2: i doesn't get the 1st hat and i can take n-1 values, so now we need to get f(n-1) values
//               giving us n-1*f(n-1);

// hence f(n)=(n-1)*(f(n-1)+f(n-2)); dearrangements

//STARS AND BAR (k stars and n bars) ((k+n-1)C(n-1))  x1+x2+x3...xn=k Xi>=0; or N boxes and K balls, can put multiple balls in a box
// x1+p+x2+p+x3+p....=k
//x1+x2+...=k-p-p-p...
//x1+x2+x3..=k'
// k'+(n-1)C(n-1)

//pos[0]=true;
//for(k=0;k<n;k++){for(x=W;x>=0;x--;){if(pos[x]){pos[x+wt[k]]=true;}}}

void solve() {
    int W,n;cin>>W>>n;
    int tot=0;
    vector<array<int,3>>v(n);
     vector<int>wt,val;
    for(int i=0;i<n;i++){
        cin>>v[i][0]>>v[i][1]>>v[i][2];
        tot+=v[i][2];
        for(int j=0;j<v[i][2];j++){
            wt.push_back(v[i][1]);
            val.push_back(v[i][0]);
        }
    }
    //cout<<v[0][1];
    vector<int>dp(W+1,0);
    dp[0]=0;
    for(int i=0;i<tot;i++){
        for(int j=W;j>=0;j--){
            if(j-wt[i]>=0&&dp[j-wt[i]]+val[i]>dp[j]){
                dp[j]=dp[j-wt[i]]+val[i];
            }
        }
    }
  cout<<dp[W];
}
int main(){
 //freopen("team.in","r",stdin);
 //freopen("team.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t=1;
   // cin>>t;
    while(t--){
       solve();
    }
}
// 4
// 2
// 1
// 2
// 3
// 4

#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...