终于AC了,不过希望有人能对我的代码提出改进建议

P1064 [NOIP2006 提高组] 金明的预算方案

liysjianttso @ 2023-08-25 15:49:01

不妨看看我花了一小时脑子一抽写的离谱代码:

// Problem: P1064 [NOIP2006 提高组] 金明的预算方案
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1064
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define MA 1000010

int n,m,u[MA],p[MA],cnt,c,dp[MA];
int uu[MA],pp[MA];

vector<int> v[MA]; //第i个有哪些附属
vector<int> mas;    //不是附属的有哪些

int f[1000][1000];//分组背包,第i组有哪些下标
int b[MA]; //第i组有几个物品

int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i<=m;i++){
        int k;
        scanf("%d%d%d",&u[i],&p[i],&k);
        if(k!=0)v[k].push_back(i);//第k个的附属加上这个
        else mas.push_back(i);//不是附属的加一个
    }
    for(int i = 0;i<mas.size();i++){
        //mas[i]为当前不是附属的
        int mu = u[mas[i]],mp = p[mas[i]];
        if(v[mas[i]].size()==0){
            //一个服书也没有
            uu[++cnt] = mu;
            pp[cnt] = mp*mu;

            c++; //c为组下标
            b[c] = 1; //第c组数量
            f[c][b[c]] = cnt;
        }
        else if(v[mas[i]].size()==1){
            //一个附属
            uu[++cnt] = mu;
            pp[cnt] = mp*mu;

            c++; //c为组下标
            b[c] = 1; //第c组数量
            f[c][b[c]] = cnt;

            int v1 = v[mas[i]][0];//第一个附属的下标
            uu[++cnt] = mu+u[v1];
            pp[cnt] = mp*mu+p[v1]*u[v1];
            //c++; //c为组下标
            b[c] = 2; //第c组数量
            f[c][b[c]] = cnt;
        }
        else if(v[mas[i]].size()==2){
            //两个附属
            uu[++cnt] = mu;
            pp[cnt] = mp*mu;

            c++; //c为组下标
            b[c] = 1; //第c组数量
            f[c][b[c]] = cnt;

            int v1 = v[mas[i]][0];//第一个附属的下标
            uu[++cnt] = mu+u[v1];
            pp[cnt] = mp*mu+p[v1]*u[v1];

            //c++; //c为组下标
            b[c] = 2; //第c组数量
            f[c][b[c]] = cnt;

            int v2 = v[mas[i]][1]; //第二个附属的下标(反正最多两个)
            uu[++cnt] = mu+u[v2];
            pp[cnt] = mp*mu+p[v2]*u[v2];

            //c++; //c为组下标
            b[c] = 3; //第c组数量
            f[c][b[c]] = cnt;

            uu[++cnt] = mu+u[v1]+u[v2];
            pp[cnt] = mp*mu+p[v1]*u[v1]+p[v2]*u[v2];

            //c++; //c为组下标
            b[c]=4; //第c组数量
            f[c][b[c]] = cnt;
        }
    }
    /*
    for(int i = 1;i<=c;i++){
        for(int j = 1;j<=b[i];j++){
            printf("%d %d %d\n",f[i][j],uu[f[i][j]],pp[f[i][j]]);
        }
        printf("----------\n");
    }*/
    for(int i = 1;i<=c;i++){
        for(int j = n;j>=0;j--){
            for(int k = 1;k<=b[i];k++){
                int now = f[i][k];
                //printf("%d %d %d\n",now,uu[now],pp[now]);

                if(j>=uu[now]){
                    //printf(":%d %d --> ",dp[j],dp[j-uu[now]]+pp[now]);
                    dp[j] = max(dp[j],dp[j-uu[now]]+pp[now]);
                    //printf("%d\n",dp[j]);
                }

            }
        }
    }
    printf("%d",dp[n]);
    return 0;
}

分组过程不知道能不能再优化一下,太恶心了


by liysjianttso @ 2023-08-25 15:50:51

改了老多回了,所以有些迷惑行为

比如b[c] = 2;b[c] = 3这样


by rnf5114 @ 2023-08-25 16:06:13

A了这道题,祝你们成功(雾


by lizuting @ 2023-08-25 16:07:42

@liysjianttso 我的:

#include <bits/stdc++.h>
using namespace std;
const int N = 32005;
int n, m, mw[N], mv[N], fw[N][3], fv[N][3], f[N], v, p, q;
int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i ++) {
        cin >> v >> p >> q;
        if (!q) {
            mw[i] = v;
            mv[i] = v * p;
        }
        else  {
            fw[q][0] ++;
            fw[q][fw[q][0]] = v;
            fv[q][fw[q][0]] = v * p; 
        }
    }
    for (int i = 1; i <= m; i ++) {
        for (int j = n; j >= mw[i]; j --) {
            f[j] = max(f[j], f[j - mw[i]] + mv[i]);
            if (j >= mw[i] + fw[i][1]) f[j] = max(f[j], f[j - mw[i] - fw[i][1]] + mv[i] + fv[i][1]);
            if (j >= mw[i] + fw[i][2]) f[j] = max(f[j], f[j - mw[i] - fw[i][2]] + mv[i] + fv[i][2]);
            if (j >= mw[i] + fw[i][1] + fw[i][2])
                f[j] = max(f[j], f[j - mw[i] - fw[i][1] - fw[i][2]] + mv[i] + fv[i][1] + fv[i][2]);
        }
    }
    cout << f[n] <<endl;
    return 0;
}

by liysjianttso @ 2023-08-25 16:37:52

@zyc111111 确实比我这个好很多,感谢


by lizuting @ 2023-08-25 16:45:49

@liysjianttso 不用谢,我也是听的教练讲的


|