P1455 搭配购买
P1455 搭配购买 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一个背包和并查集结合的题目,把需要一起购买的东西绑在一起,后面用01背包求出最大的价值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int fa[100005],p[10010],v[10010],f[10010];
void unionn(int a,int b);
int find(int i);
int main()
{
int n,m,w,i,j;
cin>>n>>m>>w;
for(i=1;i<=n;i++){
fa[i]=i;//初始化
cin>>p[i]>>v[i];
}
for(i=1;i<=m;i++){
int x,y;
cin>>x>>y;
unionn(x,y);//合并需要一起购买的
}
for(i=1;i<=n;i++){//01背包
if(find(fa[i]==i))//判断是不是根节点,价格累加在这里
for(j=w;j>=p[i];j--){
f[j]=max(f[j],f[j-p[i]]+v[i]);
}
}
cout<<f[w];
}
void unionn(int a1,int b1)
{
int i,j;
i=find(a1);
j=find(b1);
if(i!=j){
p[j]+=p[i];
v[j]+=v[i];
fa[i]=j;
}
}
int find(int i)
{
if(fa[i]==i)
{
return i;
}
else{
fa[i]=find(fa[i]);
return fa[i];
}
}
P2080 增进感情
P2080 增进感情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
每个活动都可以选择做或者不做(好像和背包一样)从第一个活动搜索到最后一个枚举所有组合,可以考虑的一个剪枝是已经最幸福的时候就不用继续了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[50][2];
int ans=0x3f3f3f3f,xm=0,xh=0,v,n;
void dfs(int num);
int main()
{
int i;
cin>>n>>v;
for(i=1;i<=n;i++)
{
cin>>a[i][0]>>a[i][1];
}
dfs(1);//参数表示第几个活动
if(ans==0x3f3f3f3f)cout<<-1;//不能在一起就释怀 输出-1
else cout<<ans;
}
void dfs(int num)
{
if(num<=n){
for(int i=0;i<=1;i++)//两种选择做或者不做
{
if(i){
xm+=a[num][0];
xh+=a[num][1];
}
if(xm+xh>v){
ans=min(ans,abs(xm-xh));//更新答案
if(ans==0)return;//如果已经是幸福生活就不用继续了
}
dfs(num+1);//下一个活动
if(i){//回溯,只需要恢复做过的
xm-=a[num][0];
xh-=a[num][1];
}
}
}
else return;
}