HDU-2602 Bone Collector(01背包)

HDU-2602 Bone Collector(01背包)

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

 

Problem Description

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

 

 

 

Input

The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

 

 

Output

One integer per line representing the maximum of the total value (this number will be less than 231).

 

 

Sample Input

 

15 101 2 3 4 55 4 3 2 1

 

Sample Output

 

14

 

 

Author

Teddy

 

 

Source

HDU 1st “Vegetable-Birds Cup” Programming Open Contest

 

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  1203 2159 2955 1171 2191 

 

01背包(ZeroOnePack): 有N件物品和一个容量为V的背包。(每种物品均只有一件)第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

01背包就是取还是不取的问题

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 1010
int dp[MAXN][MAXN];  //dp[i][j]表示i个物品,体积为j时的最大价值
int value[MAXN],w[MAXN];
int main()
{
   int t;
   int n,v;
   int i,j;
   scanf("%d",&t);
   while(t--)
   {
     int maxn=-1;
     memset(dp,0,sizeof(dp));
     scanf("%d%d",&n,&v);
     for(i=1;i<=n;i++)
     scanf("%d",&value[i]);
     for(i=1;i<=n;i++)
     scanf("%d",&w[i]);
     for(i=1;i<=n;i++)
     for(j=v;j>=0;j--)          //体积是从大到小变化的, for(j=0;j<=v;j++) 也是可以的
     {                          //也就是说这里是有两种情况讨论的

         if(j>=w[i])
         dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+value[i]);//不要当前物品是i-1来的,
         //要也是i-1来的
         else
         dp[i][j]=dp[i-1][j];   //一开始是没这个物品的,装不下的话也只能这样
                                //当前的i是要保存值的。
         maxn=max(maxn,dp[i][j]);   //不一定就是取n个物品价值最大
     }
     cout<<maxn<<endl;
   }
    return 0;
}

 

PAT (Top Level) Practice PTA1002 Business (35 分)

As the manager of your company, you have to carefully consider, for each project, the time taken to finish it, the deadline, and the profit you can gain, in order to decide if your group should take this project. For example, given 3 projects as the following:

  • Project[1] takes 3 days, it must be finished in 3 days in order to gain 6 units of profit.
  • Project[2] takes 2 days, it must be finished in 2 days in order to gain 3 units of profit.
  • Project[3] takes 1 day only, it must be finished in 3 days in order to gain 4 units of profit.

You may take Project[1] to gain 6 units of profit. But if you take Project[2] first, then you will have 1 day left to complete Project[3] just in time, and hence gain 7 units of profit in total. Notice that once you decide to work on a project, you have to do it from beginning to the end without any interruption.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤50), and then followed by N lines of projects, each contains three numbers P, L, and D where P is the profit, L the lasting days of the project, and D the deadline. It is guaranteed that L is never more than D, and all the numbers are non-negative integers.

Output Specification:

For each test case, output in a line the maximum profit you can gain.

Sample Input:

4
7 1 3
10 2 3
6 1 2
5 1 1

Sample Output:

18

 不降维解法:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 55
struct Node
{
    int  cost;
    int  l;
    int  t;
}a[MAXN];
int dp[55][10000];
bool cmp(Node a,Node b)
{
    return a.t<b.t;
}
int main()
{
    int  n,i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&a[i].cost,&a[i].l,&a[i].t);
    }
    sort(a+1,a+n+1,cmp);
    int maxn=-1;
    int deadline=a[n].t;
    for(i=1;i<=n;i++)
    for(j=deadline;j>=0;j--)
    {
            if(j>a[i].t) continue;     //枚举所有的情况
            else
            {
                if(j>=a[i].l)
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i].l]+a[i].cost);
                else
                dp[i][j]=dp[i-1][j];
            }
            maxn=max(maxn,dp[i][j]);   //不一定取n件物品价值就是最高
    }
    printf("%d\n",maxn);
    return 0;
}

降维解法:

时间一维为dp,枚举的for循环不降维

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN  1000
struct Node
{
    int  cost;
    int  l;
    int  t;
}a[MAXN];
int dp[100000];
bool cmp(Node a,Node b)
{
    if(a.t!=b.t)
    return a.t<b.t;
    else
    return a.l<b.l;
}    //这个排序是有必要的,贪心的思想,期限短的先处理。
int main()
{
    int  n,i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&a[i].cost,&a[i].l,&a[i].t);
    }
    sort(a+1,a+n+1,cmp);
    int deadline=a[n].t;
    int  maxn=-1;
    for(i=1;i<=n;i++)
    for(j=deadline;j>=0;j--)
    {
        if (j > a[i].t) continue;
        else
        {
            if(j>=a[i].l)  dp[j]=max(dp[j],dp[j-a[i].l]+a[i].cost);
            else           dp[j]=dp[j];
        }
        maxn=max(maxn,dp[j]);
    }
    printf("%d\n",maxn);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值