动态规划(1):01背包

1200: VIJOS-P1334
时间限制: 0 Sec 内存限制: 128 MB
提交: 1 解决: 1
[提交][状态][讨论版][命题人:外部导入]
题目描述

航天飞机的体积有限,当然如果载过重的物品,燃料会浪费很多钱, 每件食品都有各自的体积、质量以及所含卡路里,在告诉你体积 和质量的最大值的情况下,请输出能达到的食品方案所含卡路里 的最大值,当然每个食品只能使用一次.

输入

第一行 两个数 体积最大值(< 400)和质量最大值(< 400) 第二行 一个数 食品总数N(< 50). 第三行-第3+N行 每行三个数 体积(< 400) 质量(< 400) 所含卡路里(< 500)

输出

一个数 所能达到的最大卡路里(int范围内)

样例输入
320 350
4
160 40 120
80 110 240
220 70 310
40 400 220

样例输出
550
思路:01背包;

#include<iostream>
#include<algorithm>
#include<cstring>
const int maxn=55;
int a[maxn],b[maxn],c[maxn];
int f[401][401]; 
using namespace std;
int main()
{
    int Vmax,Mmax,n;
    memset(f,0,sizeof(f));\\初值0cin>>Vmax>>Mmax;
    cin>>n;
    int i,j,k;
    for(i=1;i<=n;i++)
    {
        cin>>a[i]>>b[i]>>c[i];\\体积,质量,价值;
    }
    for(k=1;k<=n;k++)
    {
    for(i=Vmax;i>=a[k];i--)//体,打一个只有k=1,2,,,i的表
    for(j=Mmax;j>=b[k];j--)//质
    {
        f[i][j]=max(f[i][j],f[i-a[k]][j-b[k]]+c[k]); \\相当于01背包的那个表;max比较,得最优;
    }
    }
    cout<<f[Vmax][Mmax]<<endl;\\输出最大容积,质量时
 } 

1182: VIJOS-P1313
时间限制: 1 Sec 内存限制: 128 MB
提交: 3 解决: 0
[提交][状态][讨论版][命题人:外部导入]
题目描述

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子: 主件 附件 电脑 打印机,扫描仪 书柜 图书 书桌 台灯,文具 工作椅 无         如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是10元的整数倍)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。         设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,……,jk,则所求的总和为:v[j1]*w[j1]+v[j2]*w[j2]+  …+v[jk]*w[jk]。(其中*为乘号)请你帮助金明设计一个满足要求的购物单。 

输入

    输入文件的第1行,为两个正整数,用一个空格隔开: N    m  其中N(< 32000)表示总钱数,m(< 60)为希望购买物品的个数。) 从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有3个非负整数 v    p    q (其中v表示该物品的价格(v< 10000),p表示该物品的重要度(1~5),q表示该物品是主件还是附件。如果q=0,表示该物品为主件,如果q> 0,表示该物品为附件,q是所属主件的编号) 

输出

      输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值 (< 200000)。 
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct NODE{
    int price;
    int imp;
    int ci;
}a[65];
int ci[65];
int dp[32010];
int main()
{
    int n,m;
    cin>>n>>m;
    memset(dp,0,sizeof(dp));

    for(int i=1;i<=m;i++)
    {
        cin>>a[i].price>>a[i].imp>>a[i].ci; 
        if(a[i].ci)
        {
            if(ci[0])
            {
                ci[1]=a[i].ci;
            }
            else ci[0]=a[i].ci;
        }
   }
    for(int i=1;i<=m;i++)
    {
        for(int j=n;j>=a[i].price;j--)
        {
            if(!a[i].ci)
            {
                dp[j]=max(dp[j],dp[j-a[i].price]+a[i].imp*a[i].price);
            }
            if(j&&ci[0]&&(j-a[i].price-a[ci[0]].price)>=0)dp[j]=max(dp[j],dp[j-a[i].price-a[ci[0]].price]+a[ci[0]].price*a[ci[0]].imp+a[i].imp*a[i].price);
            if(j&&ci[1]&&(j-a[i].price-a[ci[1]].price)>=0)dp[j]=max(dp[j],dp[j-a[i].price-a[ci[1]].price]+a[ci[1]].price*a[ci[1]].imp+a[i].imp*a[i].price);
            if(j&&ci[1]&&ci[0]&&(j-a[i].price-a[ci[0]].price-a[ci[1]].price)>=0)dp[j]=max(dp[j],dp[j-a[i].price-a[ci[0]].price-a[ci[1]].price]+a[ci[0]].price*a[ci[0]].imp+a[ci[1]].price*a[ci[1]].imp+a[i].imp*a[i].price);
        }
    }
    cout<<dp[n]<<endl;
 } 

1186: VIJOS-P1317
时间限制: 0 Sec 内存限制: 128 MB
提交: 10 解决: 0
[提交][状态][讨论版][命题人:外部导入]
题目描述

金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N 元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N 元。于是,他把每件物品规定了一个重要度,分为5 等:用整数1~5 表示,第5 等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N 元(可以等于N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。设第j 件物品的价格为v[j],重要度为w[j],共选中了k 件物品,编号依次为j1…jk,则所求的总和为:v[j1]*w[j1]+..+v[jk]*w[jk]请你帮助金明设计一个满足要求的购物单.

输入

输入的第1 行,为两个正整数,用一个空格隔开: N m (其中N(< 30000)表示总钱数,m(< 25)为希望购买物品的个数。) 从第2 行到第m+1 行,第j 行给出了编号为j1 的物品的基本数据,每行有2 个非负整数 v p (其中v 表示该物品的价格(v≤10000),p 表示该物品的重要度(1~5))

输出

输出只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的 最大值(< 100000000)

样例输入
1000 5
800 2
400 5
300 5
400 3
200 2

样例输出
3900


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct NODE{
    int price;
    int imp;
}a[30],t;
long long int hu[40],f[30010];
int main()
{
    int n,m;
    char ch;
    cin>>n>>m; 
    {
    for(int i=1;i<=m;i++)
    {
        cin>>a[i].price>>a[i].imp;
    }
    for(int i=1;i<=m;i++)
    {
       hu[i]=a[i].imp*a[i].price;
    }
    memset(f,0,sizeof(f));
    for(int i=1;i<=m;i++)
    {
        for(int j=n;j>=a[i].price;j--)
        {
            f[j]=max(f[j],f[j-a[i].price]+hu[i]);
        }
    }
    cout<<f[n]<<endl;
    } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值