zoukankan      html  css  js  c++  java
  • 【luogu P1064】 金明的预算方案

    https://www.luogu.org/problemnew/show/P1064

      从题目描述中可以很清楚地看出这是一个背包问题, 并且只有两类物品:主件和附件。所以这是一个非树形有依赖的背包问题。先对每种主件的 附件的集合 进行一次 01背包处理,就可以先求出 对于每一种主件包括其附件的组合中,每种花费的最大价值。

    这样可以得到主件k的附件中费用依次为0nv[k]时的相应最大价值f[0nv[k]],那么我们就得到了主件k及其附件集合的nv[k]+1种不同选择情况,其中费用为v[k]+t的物品的价值就是f[t]+v[k]p[k]。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    struct node {
        int v, p, q;
    } a[65], p[65][65];
    int n, m;
    int t[65], V[65][15], F[65][15], cnt[65], f[32005], ans;
    int main() {
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= m; i++) {
            scanf("%d %d %d", &a[i].v, &a[i].p, &a[i].q);
            if(a[i].p) {
                t[a[i].q]++;
                p[a[i].q][t[a[i].q]].v = a[i].v;
                p[a[i].q][t[a[i].q]].p = a[i].p;
                p[a[i].q][t[a[i].q]].q = a[i].q;
            }
        }
        for(int i = 1; i <= m; i++) {
            if(t[i]) {
                memset(f,-1,sizeof(f));
                f[0] = 0;
                for(int j = 1; j <= t[i]; j++)
                    for(int k = n - a[i].v; k >= p[i][j].v; k--)
                        if(f[k] < f[k - p[i][j].v] + p[i][j].v * p[i][j].p && f[k - p[i][j].v] != -1)
                            f[k] = f[k - p[i][j].v] + p[i][j].v * p[i][j].p;
                for(int j = 0; j <= n - a[i].v; j++)
                    if(f[j] != -1) {
                        cnt[i]++;
                        V[i][cnt[i]] = j + a[i].v;
                        F[i][cnt[i]] = f[j] + a[i].v * a[i].p;
                    }
            }
            if(!a[i].q) {
                cnt[i]++;
                V[i][cnt[i]] = a[i].v;
                F[i][cnt[i]] = a[i].v * a[i].p;
            }
        }
        memset(f,0,sizeof(f));
        for(int i = 1; i <= m; i++)
            for(int j = n; j >= 0; j--)
                for(int k = 1; k <= cnt[i]; k++)
                    if(j >= V[i][k])
                        f[j] = max(f[j],f[j - V[i][k]] + F[i][k]);
        for(int i = 0; i <= n; i++)
            ans = max(ans,f[i]);
        printf("%d",ans);
        return 0;
    }
    View Code

     

  • 相关阅读:
    Java Singleton 单例模式
    android 让真机显示 DeBug Log调试信息
    android 图片处理经验分享
    android GridView 的使用 实现多项选择
    Spark/Storm/Flink
    Https
    Netty
    Netty
    java 线程状态相关测试
    Socket buffer 调优相关
  • 原文地址:https://www.cnblogs.com/jiqimin/p/11030989.html
Copyright © 2011-2022 走看看