您的位置:首页 > 其它

加了限制条件的动态规划

2017-05-14 16:52 281 查看
对于加了限制条件的动态规划,经常需要进行输入数据的预处理
题目:购物单问题====================================================

王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件附件
电脑打印机,扫描仪
书柜图书
书桌台灯,文具
工作椅
如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
    设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
    请你帮助王强设计一个满足要求的购物单。
注意:(1)先进行输入数据的预处理。这里重要度没有优先级问题,也就是说没有重要度比较高就先选,而是一个权重问题而已,所以可以设置W=价格x重要度,只需求出最大的W即可。(2)附件的问题。选附件时必须先选择主件,所以这个输入好像是有顺序的。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
using namespace std;

int main(){
int v[61];  //每件物品的价格
int vp[61];  //每件物品的价格和重要度的乘积
int q[61];   //所属附件
int dp[61][32001];
int N;
int m;
while(cin>>N>>m){
for(int i=0;i<61;i++){
memset(dp[i],0,sizeof(dp[i]));
}
int impor;
for(int i=1;i<=m;i++){

cin>>v[i]>>impor>>q[i];
vp[i]=v[i]*impor;
}

for(int i=1;i<=m;i++){
for(int j=1;j<=N;j++){
if(q[i]==0){
if(v[i]<=j){
dp[i][j]=max(dp[i-1][j-v[i]]+vp[i],dp[i-1][j]);
}
}
else{
if(v[i]+v[q[i]]<=j){
dp[i][j]=max(dp[i-1][j-v[i]]+vp[i],dp[i-1][j]);
}
}
}
}
cout<<dp[m]
<<endl;
}
return 0;
}

这里有个小疑问: 这样会不会造成全部选的都是附件,因为程序并没有在选附件的条件下先选主件,而只是判断(附件+主件的重量)<j。 除非输入的顺序是先输入主件,属于这个主件的附件在这个主件后输入。如果输入顺序是随意的,比如过前10个输入的全是附件,那好像就会造成这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划