제출 #1363621

#제출 시각아이디문제언어결과실행 시간메모리
1363621CowTheCowKnapsack (NOI18_knapsack)C++20
100 / 100
44 ms34228 KiB
#include <bits/stdc++.h>

#define int long long
#define double long double
#define vi vector<int>
#define pb push_back
#define sz(a) a.size()
#define pii pair<int,int>
#define fi first
#define se second
#define all(a) a.begin(), a.end()

using namespace std;

void setIO(string s) {
	freopen((s + ".in").c_str(), "r", stdin);
	freopen((s + ".out").c_str(), "w", stdout);
}

const int MAXW=2001;

vector<pii> weights [MAXW];
int cost [MAXW][MAXW]; //using items of weight i, what is maximum price of items with a total weight of j
int dp [MAXW];
int ndp [MAXW];

void solve() {

    int s,n;
    cin>>s>>n;

    for(int i=0;i<n;i++) {
        int p, w, f; //price weight freq
        cin>>p>>w>>f;
        weights[w].pb({p,f});
    }

    for(int i=0;i<=s;i++) 
        fill(cost[i], cost[i]+s, 0);
     
    for(int i=1;i<=s;i++) {
        if(!weights[i].empty()) {
            sort(all(weights[i])); //sorted by price
            reverse(all(weights[i]));

            int tot=0;
            int ptr=0;
            for(int tw=i;tw<=s;tw+=i) {
                if(weights[i][ptr].se==0) {
                    ptr++;
                }
                if(ptr>=sz(weights[i])) break;
                
                tot+=weights[i][ptr].fi;
                weights[i][ptr].se--;
                cost[i][tw]=tot;
            }
        }
    }

    fill(dp, dp+s, 0);
    for(int i=1;i<=s;i++) {
        vector<pii> cur;
        for(int j=i;j<=s;j+=i) {
            if(cost[i][j]==0) break;
            cur.pb({cost[i][j], j});
        }

        for(int j=1;j<=s;j++) {
            for(auto [val, weight]:cur) { //limited by harmonic series
                if(j>=weight) {
                    ndp[j]=max(ndp[j], dp[j-weight]+val);
                }
            }            
        }
        memcpy(dp, ndp, sizeof ndp);
    }

    //push dp
    //set weight to 0
    //then go through all the 1-weight items, process the 2000 possible states
    //then go through the entire dp array again going through 2-weight, there are 1000 possible states now
    //3-weight has 2000/3 states
    //etc
    //in total there aren't that many states
    //then do another DP going through weight and state?
    int ans=0;
    for(int i=0;i<=s;i++)
        ans=max(ans, dp[i]);

    cout<<ans<<"\n";
}

signed main() {

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t=1;
    // cin>>t;

    while(t>0) {
        solve();
        t--;
    }
}

컴파일 시 표준 에러 (stderr) 메시지

knapsack.cpp: In function 'void setIO(std::string)':
knapsack.cpp:16:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   16 |         freopen((s + ".in").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
knapsack.cpp:17:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   17 |         freopen((s + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…