首页 > 其他分享 >洛谷题单指南-动态规划1-P1064 [NOIP2006 提高组] 金明的预算方案

洛谷题单指南-动态规划1-P1064 [NOIP2006 提高组] 金明的预算方案

时间:2024-04-22 15:11:06浏览次数:16  
标签:NOIP2006 主件 idx int 洛谷题 附件 体积 物品 P1064

原题链接:https://www.luogu.com.cn/problem/P1064

题意解读:用固定钱数购买最大价值的物品。

解题思路:

背包问题,背包问题里的体积相当于物品价格,价值相当于价格 * 重要度

物品分为主件、附件,主件最多有0/1/2个附件,要选附件必须选相应主件,

因此在递推计算dp[j]总价格j能购买的最大价值时,对于第i个主件,可以有5种可能:

1、不买第i个主件任何物品

2、只买第i个主件

3、买第i个主件和他的第1个附件(如果有)

4、买第i个主件和他的第2个附件(如果有)

5、买第i个主件和他的1,2两个附件(如果有)

求最大值即可,直接用此方式进行递推求解也没问题,但本题用另外一种更接近标准模版的方法。

既然以上5种情况每次只选一种,那么该问题可以转化为分组背包问题:

每个主件就是一个分组,根据主件的附件数量不同,分组里有不同的物品:

1、分组里第0个物品的体积、价值都是0,表示不选该分组

2、如果一个主件有0个附件,则该组只有一个物品,对应主件的体积和价值

3、如果一个主件有1个附件,则该组有两个物品, 物品1:主件的体积和价值, 物品2:主件+附件的体积和价值 4、 如果一个主件有2个附件,则该组有四个物品, 物品1:主件的体积和价值, 物品2:主件+附件1的体积和价值, 物品3:主件+附件2的体积和价值, 物品4:主件+物品1+物品2的体积和价值 将物品分组之后,就可以用分组背包的模版代码实现DP过程。 100分代码:
#include <bits/stdc++.h>
using namespace std;

const int N = 65, V = 32005;

struct node
{
    int v; //体积 : 对应价格
    int w; //价值 : 对应价格 * 重要度
};

int no[N]; //所有主件的物品编号
int cnt; //主件数量
node a[N]; //主件
vector<node> b[N]; //主件对应的附件
vector<node> g[N]; //g[i]表示第i组的所有物品
int dp[V]; //dp[j]表示总价格是j的最大价值
int n, m, v, p, q;

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> v >> p >> q;
        if(q == 0) //存主件
        {
            no[++cnt] = i;
            a[i].v = v;
            a[i].w = v * p;
        }
        else b[q].push_back({v, v * p}); //存主件对应的附件
    }
     
    /*
        将主件和对应的附件处理成分组
        每个主件对应一个组,
        如果一个主件有0个附件,则该组只有一个物品,对应主件的体积和价值
        如果一个主件有1个附件,则该组有两个物品,物品1:主件的体积和价值,物品2:主件+附件的体积和价值
        如果一个主件有2个附件,则该组有四个物品,物品1:主件的体积和价值,物品2:主件+附件1的体积和价值,物品3:主件+附件2的体积和价值,物品4:主件+物品1+物品2的体积和价值
        所有分组都有一个体积、价值为0的物品,表示不选该分组任何物品
    */
    for(int i = 1; i <= cnt; i++)
    {
        int idx = no[i];
        g[idx].push_back({0, 0}); //每个分组可以不选,分组第0个物品体积和价值都是0表示不选该组
        g[idx].push_back({a[idx].v, a[idx].w});
        if(b[idx].size() >= 1)
        {
            g[idx].push_back({a[idx].v + b[idx][0].v, a[idx].w + b[idx][0].w});
        }
        if(b[idx].size() >= 2)
        {
            g[idx].push_back({a[idx].v + b[idx][1].v, a[idx].w + b[idx][1].w});
            g[idx].push_back({a[idx].v + b[idx][0].v + b[idx][1].v, a[idx].w + b[idx][0].w + b[idx][1].w});
        }
    }
  
    //下面采用分组背包的算法
    for(int i = 1; i <= cnt; i++)
    {
        int idx = no[i];
        for(int j = n; j >= 0; j--)
        {
            for(int k = 0; k < g[idx].size(); k++)
            {
                if(j >= g[idx][k].v) dp[j] = max(dp[j], dp[j - g[idx][k].v] + g[idx][k].w);
            }
        }
    }
    cout << dp[n];

    return 0;
}

 

标签:NOIP2006,主件,idx,int,洛谷题,附件,体积,物品,P1064
From: https://www.cnblogs.com/jcwy/p/18150674

相关文章

  • 洛谷题单指南-动态规划1-P3842 [TJOI2007] 线段
    原题链接:https://www.luogu.com.cn/problem/P3842题意解读:计算1-n的最短路,且每行要覆盖线段。解题思路:既然要每行覆盖线段,那往下一行走时,必然是从线段的端点往下,有可能是从左端点往下,也有可能是从右端点往下。当已知第i行,从1走到第i行的左端点且要覆盖第i行线段的路程可以计算......
  • 洛谷题单指南-动态规划1-P1077 [NOIP2012 普及组] 摆花
    原题链接:https://www.luogu.com.cn/problem/P1077题意解读:n种花选m个的选法,每种花数量为ai。解题思路:设dp[i][j]表示前i种花选j个的选法对于第i种花,可以选0,1,2...min(ai,j)个则有递推式:dp[i][j]=∑dp[i-1][j-k],k取0,1,2...min(ai,j)初始化dp[0][0]=1100分代码:#incl......
  • 洛谷题单指南-动态规划1-P1049 [NOIP2001 普及组] 装箱问题
    原题链接:https://www.luogu.com.cn/problem/P1049题意解读:装尽可能多的物品,使得总体积越大越好,即剩余空间最小,还是一个01背包问题,物品的体积就是其价值。解题思路:01背包模版题,物品体积、价值相同,直接采用一维dp。100分代码:#include<bits/stdc++.h>usingnamespacestd;co......
  • 洛谷题单指南-动态规划1-P1115 最大子段和
    原题链接:https://www.luogu.com.cn/problem/P1115题意解读:计算最大字段和,典型dp问题。解题思路:设a[]表示所有整数,f[i]表示以第i个数结束的最大字段和当f[i-1]>=0时,f[i]=f[i-1]+a[i]否则,f[i]=a[i]因此,递归式为f[i]=max(a[i],f[i-1]+a[i])注意整数可能为负,ans初始......
  • 洛谷题单指南-动态规划1-P1434 [SHOI2002] 滑雪
    原题链接:https://www.luogu.com.cn/problem/P1434题意解读:计算能滑行的最长距离。解题思路:设dp(i,j)表示从i,j可以滑行的最大距离对于4个方向i,j可以到达的点,ni,nj,如果可以滑过去(ni,ni所在点高度更低)则dp(i,j)=max(dp(i,j),1+dp(ni,nj))为了便于搜索4个方向的各条路径,......
  • 洛谷题单指南-动态规划1-P2196 [NOIP1996 提高组] 挖地雷
    原题链接:https://www.luogu.com.cn/problem/P2196题意解读:求一条路径,使得所有点地雷数之和最大。解题思路:1、DFS先建图,再从1~n点分别进行一次DFS,记录过程中地雷总数最大的,并且同时记录遍历的顺序。数据量不大,直接就可以过。100分代码:#include<bits/stdc++.h>usingnamespa......
  • 洛谷题单指南-动态规划1-P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles
    原题链接:https://www.luogu.com.cn/problem/P1216题意解读:计算数字三角形最高点到最后一行路径之和最大值,典型线性DP。解题思路:设a[i][j]表示数字三角形的值,设dp[i][j]表示从最高点到第i行第j列路径之和的最大值,由于每一步可以走到左下方的点也可以到达右下方的点,所以dp[i][......
  • 洛谷题单指南-数学基础问题-P1403 [AHOI2005] 约数研究
    原题链接:https://www.luogu.com.cn/problem/P1403题意解读:计算1~n每个数的约数个数之和。解题思路:1、数学方法1~n的约数范围也在1~n,要计算每个数的约数个数之和可以从约数出发,比如约数是x,那么在1~n中一共有n/x个数包含x这个约数x从1一直枚举到n,就可以得出每个约数是多少个......
  • 洛谷题单指南-数学基础问题-P3601 签到题
    原题链接:https://www.luogu.com.cn/problem/P3601题意解读:求l~r范围内所有qiandao(x)之和,qiandao(x)为小于等于x的数中,与x不互质的数的个数。注意取模。解题思路:欧拉函数定义:phi(x)=x*(1-1/p1)*(1-1/p2)*...*(1-1/pn),p1,p2...pn为x的所有质因子其中:phi(x)表示1~x中所......
  • 洛谷题单指南-数学基础问题-P2660 zzc 种田
    原题链接:https://www.luogu.com.cn/problem/P2660题意解读:对一个长方形,切割出最少数量的正方形,计算所有正方形的边长。解题思路:长方形长、宽为x,y先判断x,y哪个长,哪个短长的作为l,短的作为s先切出s*s的正方形,一共可以切出l/s个,累加周长ans+=l/s*s*4在对剩下的s*......