Codeforces Round #383 (Div. 2)D-(并查集&分组背包)|(搜索&01背包)
来源:互联网 发布:录像软件 编辑:程序博客网 时间:2024/05/17 22:29
传送门
分组背包模板题。
用并查集搞一搞一齐的关系就好。
然后就是分组背包的模板了,注意,在分组的时候,把i组所有和加起来 这一个虚拟的物品分到 i组里,而不能独立分组,不然会造成某一个模特的的多次使用。。
或者用搜索,这个搜索用滚动数组的时候,类似于树形dp里面,在一个树内进行01背包。
但是在遍历的时候,可能会出现从0数组 转到0数组的情况(1数组先前已经被vis掉了,如果我们不处理这个结果就会发生前面的结果可能没有办法继承。)所以我们每次可以 把所有的数组 都给赋值了。
这个很重要,本菜没有想到好的方法。大家可以一起交流
dfs搜索版本
#include <bits/stdc++.h>#define MOD 1000000007#define maxn 100005using namespace std;typedef long long ll;int dp[2][1005], vis[1005];int w[1005], b[1005], h, sum1, sum2;vector<int> v[1005];int n, m, ww, a, bb;void dfs(int k,int j){ for(int i = ww; i >= w[k]; i--){ dp[j%2][i] = max(dp[(j-1)%2][i-w[k]] + b[k], dp[j%2][i]); } vis[k] = 1; sum1 += w[k]; sum2 += b[k]; for(int i = 0; i < v[k].size(); i++){ if(vis[v[k][i]] == 0){ dfs(v[k][i],j); } }}int main(){ // freopen("in.txt", "r", stdin); scanf("%d%d%d", &n, &m, &ww); for(int i = 1; i <= n; i++) scanf("%d", w+i); for(int j = 1; j <= n; j++) scanf("%d", b+j); for(int i = 1; i <= m; i++){ scanf("%d%d",&a,&bb); v[a].push_back(bb); v[bb].push_back(a);//建图,然后用搜索的方法处理,类似树形dp } for(int i=1;i<=n;i++){ sum1=0;sum2=0; //memset(vis,false,sizeof(vis)); if(!vis[i]) dfs(i,i);//一层一层的背包。 for(int j = ww; j >= sum1; j--){ dp[i%2][j] = max(dp[(i-1)%2][j-sum1] + sum2, dp[i%2][j]); } for(int x=1;x<=ww;x++) dp[(i+1)%2][x]=dp[i%2][x]; // cout<<endl; } printf("%d\n",dp[n%2][ww]); return 0;}
#include <iostream>#include <cstdio>#include <cstdlib>#include <vector>using namespace std;/*分组背包,模板题。*/const int maxn=100005;int fa[maxn];void init(int m){for(int i=0;i<maxn;i++) fa[i]=i;}int find1(int a){ if(fa[a]==a)return a; return fa[a]=find1(fa[a]);}void unite(int a,int b ){ int x=find1(a); int y=find1(b); if(x==y)return; fa[x]=y;}int c[maxn];int v[maxn];vector<int>G[maxn];int dp[maxn];int main(){ int m,n,p; int a,b; scanf("%d%d%d",&m,&n,&p); init(m*2); for(int i=1;i<=m;i++){ scanf("%d",&c[i]); } for(int i=1;i<=m;i++){ scanf("%d",&v[i]); } for(int i=1;i<=n;i++){ scanf("%d%d",&a,&b); unite(a,b); } int t=m; for(int i=1;i<=m;i++) G[find1(i)].push_back(i);//根据ufs关系来确定一个图图 for(int i=1;i<=m;i++){ int sum1=0; int sum2=0; if(!G[i].size()) continue; for(int j=0;j<G[i].size();j++){ sum1+=c[G[i][j]]; sum2+=v[G[i][j]]; } if(G[i].size()<=1) continue; c[1+t]=sum1; v[++t]=sum2; G[i].push_back(t); } /*for(int i=0;i<=t;i++){ cout<<i<<"@@"; for(int j=0;j<G[i].size();j++) printf("%d ",G[i][j]); cout<<endl; }*/ //cout<<m<<endl; for(int i=1;i<=t;i++){ if(!G[i].size()) continue; for(int j=p;j>=0;j--){ for(int k=0;k<G[i].size();k++) if(j>=c[G[i][k]]) dp[j]=max(dp[j],dp[j-c[G[i][k]]]+v[G[i][k]]); } } printf("%d\n",dp[p]); return 0;}
阅读全文
0 0
- Codeforces Round #383 (Div. 2)D-(并查集&分组背包)|(搜索&01背包)
- Codeforces Round #383 (Div. 2)D.Arpa's weak amphitheater and Mehrdad's valuable Hoses【并查集+分组背包】
- Codeforces Round #383 (Div. 2) D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(并查集+分组背包)
- Codeforces Round #383 (Div. 2) D. Arpa's weak amphitheater and Mehrdad's valuable Hoses 并查集+双重01背包
- Codeforces#383D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(并查集+分组背包)
- 分组背包+并查集
- Codeforces Round #250 (Div. 2) (D. The Child and Zoo(并查集))
- Codeforces Round #363 (Div. 2) D. Fix a Tree(并查集)(判断圆环)
- Codeforces Round #363 (Div. 2) Problem D - Fix a Tree(并查集 + 构造)
- Codeforces Round #363 (Div. 2) D. Fix a Tree(并查集)
- Codeforces Round #396 (Div. 2) D. Mahmoud and a Dictionary(并查集)
- Codeforces Round #396 (Div. 2)D. Mahmoud and a Dictionary(带权并查集)
- Codeforces Round #396 (Div. 2) D. Mahmoud and a Dictionary (并查集)
- Codeforces Round #218 (Div. 2) D. Vessels(思维 并查集)
- Codeforces Round #363 (Div. 2) D Fix a Tree(并查集)
- Codeforces Round #218 (Div. 2)---D. Vessels(并查集)
- CSU 1326: The contest(并查集+分组背包)
- Codeforces Round #273 (Div. 2)D. Red-Green Towers(背包)
- SQLite增删查改语句
- JSON字符串转JSON对象
- 点击跳转网址
- 多线程通信( wait(),notify(),notifyAll() )
- Aandroid 储存方式
- Codeforces Round #383 (Div. 2)D-(并查集&分组背包)|(搜索&01背包)
- 5-3 排序 (25分)
- #HDU4045#Machine scheduling(隔板法的思维:第二类Stirling)
- 【linux】目录_路径
- Android DIY(自定义) UI(控件,界面)
- 线程倒计时
- 一步步走通Notepad运行JAVA
- ROS导航之base_local_planner
- Android返回键确定退出