首页 > 其他分享 >luogu P1455 搭配购买

luogu P1455 搭配购买

时间:2024-11-26 16:58:37浏览次数:7  
标签:P1455 10 le int luogu cin 搭配 include

01背包

/*二维
#include <iostream>
#include <algorithm>

const int N = 1010;
int v[N], w[N], f[N][N];
using namespace std;

int main()
{
    int n, m; cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> v[i] >> w[i];
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            f[i][j] = f[i - 1][j];   //先更新到上一层的状态,因为下一行不进行的话,f[i][j]就未被赋值
            if(j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);

                //考虑是否放入物品i,就要看放入之后它能不能让价值的最大值变大
                //假设放入,用去掉第i个物品的最大值加上第i个物品的价值(递推)
        }
    }
    cout << f[n][m];
}
*/

//一维
#include <iostream>
#include <algorithm>

const int N = 1010;
int v[N], w[N], f[N];
using namespace std;

int main()
{
    int n, m; cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> v[i] >> w[i];
    for(int i = 1; i <= n; i++)  //因为背包内最终个数是多少都不重要,只要<=n个即可,由于f[i][j] = max(f[i - 1)[j], f[i - 1][j - v[i] + w[i]), 求放第i个f[j]只需要用到上一层放第i - 1个的f[j], 所以可以写成一维
    {
        for(int j = m; j >= v[i]; j--) f[j] = max(f[j], f[j - v[i]] + w[i]); //只有j >= v[i]时才会更新状态,< v[i]就是没有放入,体积不变,价值也不变
      /*for(int j = v[i]; j <= m; j++)   因为j是递增的,所以计算到f[i][j]的时候
        肯定已经计算了f[i][j - v[i]],由于现在数组是一维的,f[j - v[i]] = f[i][j - v[i]],
        但是我们需要的是f[i - 1][j - v[i]],所以不能从前往后遍历,应该从后往前,那么这样小的数就来不及更新
      */
    }
    cout << f[m];
}

搭配购买

题目描述

明天就是母亲节了,电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢?听说在某个网站上有卖云朵的,小朋友们决定一同前往去看看这种神奇的商品,这个店里有 \(n\) 朵云,云朵已经被老板编号为 \(1,2,3,...,n\),并且每朵云都有一个价值,但是商店的老板是个很奇怪的人,他会告诉你一些云朵要搭配起来买才卖,也就是说买一朵云则与这朵云有搭配的云都要买,电脑组的你觉得这礼物实在是太新奇了,但是你的钱是有限的,所以你肯定是想用现有的钱买到尽量多价值的云。

输入格式

第一行输入三个整数,\(n,m,w\),表示有 \(n\) 朵云,\(m\) 个搭配和你现有的钱的数目。

第二行至 \(n+1\) 行,每行有两个整数, \(c_i,d_i\),表示第 \(i\) 朵云的价钱和价值。

第 \(n+2\) 至 \(n+1+m\) 行 ,每行有两个整数 \(u_i,v_i\)。表示买第 \(u_i\) 朵云就必须买第 \(v_i\) 朵云,同理,如果买第 \(v_i\) 朵就必须买第 \(u_i\) 朵。

输出格式

一行,表示可以获得的最大价值。

样例

5 3 10
3 10
3 10
3 10
5 100
10 1
1 3
3 2
4 2
1

提示

对于 \(100\%\) 的数据,满足 \(1 \le n, w \le 10^4\),\(0 \le m \le 5 \times 10^3\)。

思路

将必须搭配购买的用并查集合并到一起,将价值和价钱相加,就变成了01背包

代码

#include <iostream>
#include <algorithm>

using namespace std;
const int N = 1e4 + 10;
int p[N], v[N], w[N], f[N];

int find(int x);
void uniona(int x, int y);
int main()
{
	int n, m, q; cin >> n >> m >> q;
	for(int i = 1; i <= n; i++) p[i] = i, cin >> v[i] >> w[i];
	while(m--)
	{
		int x, y; cin >> x >> y;
		int p1 = find(x), p2 = find(y);
		if(p1 != p2) uniona(p1, p2);
	}
	for(int i = 1; i <= n; i++)
	{
		if(v[i])
			for(int j = q; j >= v[i]; j--) f[j] = max(f[j], f[j - v[i]] + w[i]);
	}
	cout << f[q];
}
int find(int x)
{
	int a = x;
	while(a != p[a]) a = p[a];
	int b = x, c;
	while(b != a)
	{
		c = p[b];
		p[b] = a;
		b = c;
	}
	return a;
}
void uniona(int x, int y)
{
	p[x] = y;
	v[y] += v[x], w[y] += w[x];  //合并价钱和价值
	v[x] = 0, w[x] = 0;  //将被合并的置0,遍历时就能跳过
}

标签:P1455,10,le,int,luogu,cin,搭配,include
From: https://www.cnblogs.com/PeachyGalaxy/p/18570489/1126p

相关文章

  • 「Luogu P2466」[SDOI2008] Sue 的小球
    题目Sue和Sandy最近迷上了一个电脑游戏,这个游戏的故事发在美丽神秘并且充满刺激的大海上,Sue有一支轻便小巧的小船。然而,Sue的目标并不是当一个海盗,而是要收集空中漂浮的彩蛋,Sue有一个秘密武器,只要她将小船划到一个彩蛋的正下方,然后使用秘密武器便可以在瞬间收集到这个彩蛋......
  • 「Luogu P2501」[HAOI2006] 数字序列
    题目现在我们有一个长度为 \(n\) 的整数序列 \(a\)。但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数,也不希望改变的幅度太大。Luogu分析首先考虑subtask1:最小化要修改的数。如果正面思考一个数修改或不修改的答案,会发现答案......
  • 「Luogu P3953」[NOIP2017 提高组] 逛公园
    题目策策同学特别喜欢逛公园。公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有自环和重边。其中\(1\)号点是公园的入口,\(N\)号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花的时间。策策每天都会去逛公园,他总是从\(1\)号点进去,从\(N\)号点......
  • 「Luogu P5441」【XR-2】伤痕
    人类智慧题,然而我是蒟蒻qwq.题目X国经历了一场前所未有的大地震,人们伤痕累累,整个国家破碎不堪。为了帮助人们痊愈,也为了让X国能够生存下去,X国国王决定重建X国。国王决定先建造\(n\)座城市,由于国王喜欢奇数,所以\(n\)为奇数。城市建造完后,需要给每两座城市之间都......
  • 「Luogu P4516」[JSOI2018] 潜入行动
    题目外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY已经联系好了黄金舰队,打算联合所有JSOIer抵御外星人的进攻。在黄金舰队就位之前,JYY打算事先了解外星人的进攻计划。现在,携带了监听设备的特工已经秘密潜入了外星人的母舰,准备对外星人的通信实施监听。外星......
  • 每日一题:https://www.luogu.com.cn/problem/P1106
    题目链接:https://www.luogu.com.cn/problem/P1106#include<iostream>#include<string>usingnamespacestd;intmain(){intn,k,mu;stringnum;intt=1,wei,ti=0;;intarr[260];boolyes=0;cin>>num>>k;n=num.l......
  • [luoguP1903] 数颜色
    题意原题链接给定序列\(a\),每次查询一个区间\([l,r]\)中有多少个不同的数,或进行单点修改。sol如果不修改的话,本题就是普通莫队[luoguSP3267]D-query由于有修改,所以需要再增加一维,记录这次查询是在多少次修改以后查询的,然后在莫队代码后面添加对修改次数的处理,即暴力修改......
  • [luoguP11324] Speaker
    题意原题链接给定一个带权无根树,第\(i\)个节点上有一个数\(c_i\),每次询问给定两个点\(x,y\),在无根树上任选一点\(z\),使\(c_x+c_y+c_z-dist(x,z)-dist(z,y)\)最大,输出最大的值。sol考虑\(z\)可能有两种情况,要么是\(x\toy\)的路径上的一点\(t\),要么从路径上的一点......
  • [luoguP11323] Happy Card
    题意原题链接有\(n\)种牌,第\(i\)种牌有\(a_i\)张,每次可以出\(1\)张(单牌)、\(2\)张(对子)或\(4\)张相同的牌(四炸),或是\(3\)张相同的牌及\(1\)张不同的牌(三带一),求把牌出完最少需要多少次。sol赛时看到这道题,就想到了[luoguP2668]斗地主,由于没有顺子,因此可以直接考虑......
  • [luoguSP3267] D-query
    题意给定\(n\)个数\(a_1\cdotsa_n\)和\(q\)个查询,每次查询区间\([l,r]\)中,\(a\)的不同数的个数sol本题不强制在线,因此可以考虑离线算法,如莫队。莫队是一个非常神奇的算法,它的基本思想是:将区间进行某种排序后,通过移动\(l,r\)指针,每次移动时处理答案的增减来得到答......