不止代码:洛谷P1064 金明的预算方案+P2014选课(依赖背包)

文章目录

  • 题目描述
  • 总结
  • 解析
    • 解法1
    • 解法2
    • 代码
    • 解法3
    • 代码

题目描述

金明的预算方案
选课
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过 n元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的。
如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0个、1 个或 2 个附件。每个附件对应一个主件,附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的 n 元。于是,他把每件物品规定了一个重要度,分为 5 等:用整数1∼5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 n 元的前提下,使每件物品的价格与重要度的乘积的总和最大。

总结

本题一般性题解是自己独立写的,而且思路很简洁,复杂度也很好

但是这题WA了好几次,每次都是写的时候信心满满,交完发现不对,用数据检测才发现漏洞(老毛病了。。。)
以后应该改改这个坏习惯,应该先把思路想明白了(至少先拿点好的数据测测再交啊!

解析

解法1

由于本题的特殊限制,对于每个主件,最多可以分为五种情况:

1.都不买
2.只买主件
3.买主件与附件A
4.买主件与附件B
5.买主件与附件A、B

然后就可以转化为01背包了

但是我们岂可满足于此!

解法2

当附件很多且存在附件之后还有附件时应该怎么办呢?
深思熟虑后:啊哈!
我们把dp开成二维
dp[k][w]表示第k层依赖关系下,物品必须购买,w的钱获得的最大价值
对于处于第k层的物品A,枚举它的所有附件,将其作为第k+1层递归处理
然后尝试用第k层的dp值更新k-1层的dp值
最后,dp[0][n]就是答案
因为每个物品最多处理一次,单层递归复杂度是n
所以总时间复杂度为m*n(和01背包一样啊有木有!)
不难看出,空间复杂度也是n*m

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+100;
int n,m;
struct node{int w,v,belong;int nxt[500],nm;
}p[500];
int a,b,c;
int f[80][34050];
int jd[500];
void Try(int k,int id){for(int i=0;i<=n;i++){if(i<p[id].w) f[k][i]=-2e9;else f[k][i]=f[k-1][i-p[id].w]+p[id].v;}for(int i=1;i<=p[id].nm;i++){Try(k+1,p[id].nxt[i]);}for(int i=0;i<=n;i++) f[k-1][i]=max(f[k-1][i],f[k][i]);
}
void print(){for(int i=1;i<=n;i++) printf("%d ",f[0][i]);printf("\n");return;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",&p[i].w,&p[i].v,&p[i].belong);p[i].v*=p[i].w;if(p[i].belong) p[p[i].belong].nxt[++p[p[i].belong].nm]=i;}for(int i=1;i<=m;i++){if(p[i].belong) continue;Try(1,i);
//		print();}printf("%d",f[0][n]);return 0;
} 
/*
5 5
1 100 0
2 1 0
1 1000 2
2 2 2
6 10000 0
*/

解法3

树上dfs一边求出size和dfs序(注意是后序!
因为后序dfs序,所以子节点的dfs序比父节点小
这样我们就可以从前往后dp
𝑑𝑝[𝑖][𝑗]​表示前i个点里选j个物品的最大价值
那么转移就是:

𝑑𝑝[𝑖][𝑗]=max⁡(𝑑𝑝[𝑖−1][𝑗−1]+𝑣𝑎𝑙[𝑝𝑜𝑠[𝑖]],𝑑𝑝[𝑖−𝑠𝑖𝑧[𝑝𝑜𝑠[𝑖]]][𝑗])

前一个转移是选当前课
后一个是不选当前课(那么之前就只能选到𝑖−𝑠𝑖𝑧[𝑝𝑜𝑠[𝑖]])
最后答案就是dp[n][m]

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1800;
int n,m;
/*
op=0 被自己覆盖
op=1 被儿子覆盖
op=2 被父亲覆盖  
*/
struct node{int to,nxt;
}p[N];
int fi[N],cnt=-1,ru[N];
int v[N],belong[N];
void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}
int a,b,c;
int pos[N],dfs[N],size[N],tot;
void build(int x,int fa){size[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;build(to,x);size[x]+=size[to];}dfs[x]=++tot;pos[tot]=x;
}
int dp[N][N];
int main(){memset(fi,-1,sizeof(fi));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d%d",&belong[i],&v[i]);if(belong[i]) addline(belong[i],i);else addline(0,i);}build(0,-1);for(int i=1;i<=tot;i++){int id=pos[i];for(int j=m;j>=1;j--){dp[i][j]=max(dp[i-1][j-1]+v[id],dp[i-size[id]][j]);}}printf("%d",dp[n][m]);return 0;
} 
/*
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker最全教程——从理论到实战(六)

本篇教程持续编写了3个星期左右并且一直在完善、补充具体的细节和实践&#xff0c;预计全部完成需要1到2个月的时间。由于编写的过程中极其费时&#xff0c;并且还需要配合做一些实践&#xff08;有些实践存在一些坑&#xff0c;而且极其费时费事&#xff09;。因此目前产出的速…

P4332-[SHOI2014]三叉神经树【LCT】

正题 题目链接:https://www.luogu.com.cn/problem/P4332 题目大意 给出nnn个点的一棵有根三叉树&#xff0c;保证每个点的儿子个数为333或者000&#xff0c;每个叶子有一个权值000或111&#xff0c;每个非叶子节点的权值是它儿子中权值较多的那个&#xff0c;每次修改一个叶子…

牛客题霸 [ 环形链表的约瑟夫问题] C++题解/答案

牛客题霸 [ 环形链表的约瑟夫问题] C题解/答案 题目描述 据说著名犹太历史学家 Josephus 有过以下故事&#xff1a;在罗马人占领乔塔帕特后&#xff0c;39 个犹太人与 Josephus 及他的朋友躲到一个洞中&#xff0c;39 个犹太人决定宁愿死也不要被敌人抓到&#xff0c;于是决定…

2016 Multi-University Training Contest 1 1004 GCD(ST表+二分)

GCD 注意观察gcd⁡(al,al1,...,ar)\gcd(a_{l},a_{l1},...,a_{r})gcd(al​,al1​,...,ar​)&#xff0c;当lll固定不动的时候&#xff0c;rl...nrl...nrl...n时&#xff0c;我们可以容易的发现,随着rrr的増大&#xff0c;gcd⁡(al,al1,...,ar)\gcd(a_{l},a_{l1},...,a_{r})gcd(…

警卫站岗(树上dp)

题目描述 五一来临&#xff0c;某地下超市为了便于疏通和指挥密集的人员和车辆&#xff0c;以免造成超市内的混乱和拥挤&#xff0c;准备临时从外单位调用部分保安来维持交通秩序。 已知整个地下超市的所有通道呈一棵树的形状&#xff1b;某些通道之间可以互相望见。总经理要求…

.NET Core实战项目之CMS 第八章 设计篇-内容管理极简设计全过程

写在前面上一篇文章.NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程中我带着大家进行了权限部分的极简设计&#xff0c;也仅仅是一个基本的权限设计。不过你完全可以基于这套权限系统设计你的更复杂的权限系统&#xff0c;当然更复杂的权限系统要根据你的业务来进…

P7405-[JOI 2021 Final]雪玉【二分】

正题 题目链接:https://www.luogu.com.cn/problem/P7405 题目大意 nnn个点在坐标轴上&#xff0c;qqq次每次所有点向一个方向移动若干步&#xff0c;每个点的权值是它第一次覆盖的区间长度&#xff08;也就是一个区间只能贡献到第一次经过它的点&#xff09;。 求所有点的最终…

牛客题霸 [ 集合的所有子集] C++题解/答案

牛客题霸 [ 集合的所有子集] C题解/答案 题目描述 现在有一个没有重复元素的整数集合S&#xff0c;求S的所有子集 注意&#xff1a; 你给出的子集中的元素必须按升序排列 给出的解集中不能出现重复的元素 题解&#xff1a; 先sort一下&#xff0c;然后通过回溯实现选与不选…

2021“MINIEYE杯”中国大学生算法设计超级联赛(2)I love max and multiply(转化)

I love max and multiply Code 代码抄的std #include<bits/stdc.h> using namespace std; using lllong long; template <class Tint> T rd() {T res0;T fg1;char chgetchar();while(!isdigit(ch)) {if(ch-) fg-1;chgetchar();}while( isdigit(ch)) res(res<&…

人工智能第二课:认知服务和机器人框架探秘

这是《人工智能系列笔记》的第二篇&#xff0c;我利用周六下午完成课程学习。这一方面是因为内容属于入门级&#xff0c;并且之前我已经对认知服务和机器人框架比较熟悉。如有兴趣&#xff0c;请关注该系列 https://aka.ms/learningAI 但是学习这门课程还是很有收获&#xff0c…

洛谷P4322 最佳团伙(树上dp)

题目描述 洛谷传送门 题目描述 JSOI 信息学代表队一共有 N 名候选人&#xff0c;这些候选人从 1 到 N 编号。方便起见&#xff0c;JYY 的编号是 0 号。每个候选人都由一位编号比他小的候选人Ri推荐。如果 Ri0&#xff0c;则说明这个候选人是 JYY 自己看上的。 为了保证团队的…

CF587F-Duff is Mad【AC自动机,根号分治】

正题 题目链接:https://www.luogu.com.cn/problem/CF587F 题目大意 给出nnn个字符串sss。qqq次询问给出l,r,kl,r,kl,r,k要求输出sl..rs_{l..r}sl..r​在sks_ksk​中出现了多少次。 1≤n,q,∑∣si∣≤1051\leq n,q,\sum |s_i|\leq 10^51≤n,q,∑∣si​∣≤105 解题思路 考虑一…

牛客题霸 [最长重复子串] C++题解/答案

牛客题霸 [最长重复子串] C题解/答案 题目描述 一个重复字符串是由两个相同的字符串首尾拼接而成&#xff0c;例如abcabc便是长度为6的一个重复字符串&#xff0c;而abcba则不存在重复字符串。 给定一个字符串&#xff0c;请编写一个函数&#xff0c;返回其最长的重复字符子串…

codeforces1552 D. Array Differentiation(思维+暴力)

D. Array Differentiation 因为相减的顺序可以变化&#xff0c;所以这个环中数的正负性以及相减顺序其实是没有影响的&#xff0c;那么我们可以规定一个方向&#xff0c;然后再枚举所有可能的正负性。 设这环中点分别是 v1,v2,⋯vkv_1,v_2,⋯v_kv1​,v2​,⋯vk​&#xff0c;那…

粉刷木板(ybtoj-单调队列)

题目描述 解析 头疼 定义dp[i]:只用前i块板的最大价值 对于新加入的一个木匠&#xff1a; 不难写出dp转移式&#xff1a; dp[i]max(dp[k](i-k)*p)k表示开始刷的前一个 其中i>s i-k<l; 要是这么转移会是n^2m 所以我就不废了。。。 其实离正解很接近了 把上面移一下项&am…

P6563-[SBCOI2020]一直在你身旁【dp,单调队列】

正题 题目链接:https://www.luogu.com.cn/problem/P6563 题目大意 长度为nnn的序列aia_iai​&#xff0c;现在有一个随机[1,n][1,n][1,n]的整数&#xff0c;每次你可以花费aia_iai​询问这个数字是否大于iii&#xff0c;求猜出所有数至少要多少花费。 T≤500,∑n≤7000T\leq …

牛客题霸 [字符串的排列] C++题解/答案

牛客题霸 [字符串的排列] C题解/答案 题解&#xff1a; stl真好用&#xff0c;emmm。。。 代码&#xff1a; class Solution { public:vector<string> Permutation(string str) {if (str.empty()) return {};sort(str.begin(), str.end());vector<string>ans;i…

POJ - 3415 Common Substrings(长度不小于K的公共子串个数)

Common Substrings 后缀数组单调栈 题解1 题解2 题解3 #include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long ll; // sa[i]: 排名是i位的是第几个后缀 // rk[i]: 第i个后缀的排名是多少 // height[i]: sa[i]与s…

跳房子(ybtoj-单调队列)

文章目录题目描述解析代码thanks for reading&#xff01;题目描述 洛谷传送门 跳房子&#xff0c;也叫跳飞机&#xff0c;是一种世界性的儿童游戏&#xff0c;也是中国民间传统的体育游戏之一。 跳房子的游戏规则如下&#xff1a; 在地面上确定一个起点&#xff0c;然后在起…

使用Dapper持久化IdentityServer4

最近研究dotnet core,微软将IdentityServer4作为推荐的服务授权和验证的组件,其独立性特别适合微服务或者分布式的服务扩展验证,所以非常受广大dotnet开发人员的青睐.默认的IdentityServer4默认使用内存对象的验证和授权,而在IdentityServer的官方推荐只有Entity Framework cor…