您的位置:首页 > 其它

wiki 1155 金明的预算方案

2014-07-15 13:57 281 查看
背包九讲中提到的题目。这里简单概述一下。

1,分组的背包问题

问题描述:有N件物品和一个容量为v 的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为k组,每组物品互相冲突,最多选一件。求解将哪些物品放入背包中,使得容量不超过v,且价值最大。

for (int i = 1; i <= k; i++){
for(int v = V; v >= 0; v--){
for all item u in group k
f[v] = max {f[v], f[v-c[u]]+w[u]}
}
}


2,有依赖的背包问题:
问题描述:这种背包问题的物品之间存在某种依赖的关系。也就是说,物品i依赖于物品j,表示若选物品i,则必须要选物品j。为了简化起见,我们假设没有物品既依赖于别的物品,又被别的物品依赖。另外,没有某件物品同时依赖于多个物品。

分析:将一个主件和该主件的所有附件分到一个物品组。

#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
struct Node{
int cost,value,parent;
};
vector<Node> nodes[65];
int n,m,k;
void init(){
cin >> n >> m;
k = 0;
for(int i = 1; i <= m; i++){
int a,b,c;
cin >> a >> b >> c;
if(c==0) {
nodes[i].push_back(Node{a,b,c});
k++;
}
else{
nodes[c].push_back(Node{a,b,c});
}
}
}
int main(int argc, const char * argv[])
{
init();
int f[35000];
memset(f, -1, sizeof(f));
f[0] = 0;
for(int i = 0; i < 65; i++){
if(nodes[i].size()){
int dp[35000];
memset(dp, -1, sizeof(dp));
Node parentNode;
dp[0] = 0;
for(int j = 0; j < nodes[i].size(); j++){
if(nodes[i][j].parent!=0){
for(int u = n; u >= nodes[i][j].cost; u--){
if(dp[u-nodes[i][j].cost]!=-1){
int t = dp[u-nodes[i][j].cost]+nodes[i][j].value*nodes[i][j].cost;
if(dp[u]==-1) dp[u] = t;
else{
dp[u] = (dp[u] < t ? t : dp[u]);
}
}
}
}else{
parentNode = nodes[i][j];
}
}
vector<Node> tempnodes;
for(int j = 0; j <= n-parentNode.cost; j++){
if(dp[j]!=-1) tempnodes.push_back(Node{j+parentNode.cost, dp[j]+parentNode.value*parentNode.cost,0});
}
for(int j = n; j >= 0; j--){
int temp = 0;
for(int k = 0; k < tempnodes.size(); k++){
if(j >= tempnodes[k].cost && f[j-tempnodes[k].cost]!=-1) {
int u = f[j-tempnodes[k].cost] + tempnodes[k].value;
temp = (temp < u ? u : temp);
}
}
if (temp) f[j] = (f[j] < temp ? temp : f[j]);
}
}
}
int result = 0;
for(int i = 0; i <= n; i++) result = (result < f[i] ? f[i] : result);
cout << result << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息