HDU2602-01背包

HDU_2602 Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 49986    Accepted Submission(s): 20965


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
1

5 10

1 2 3 4 5

5 4 3 2 1

Sample Output
14
 
分析:裸01背包。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

代码:(DFS超时)

#include<iostream>
using namespace std;
const int maxnum = 1005;
int N, V;
int Max_Value = 0;
int value[maxnum];
int volume[maxnum];
//DFS未优化 一个物品选择放和不放
void DFS_Bag(int index, int sum_value, int sum_volume)
{
    if (index == N)
    {
        return;
    }
    
    //not load current thing to bag
    DFS_Bag(index + 1, sum_value, sum_volume);
    if (sum_volume + volume[index] <= V)
    {
        if (sum_value + value[index] > Max_Value)
        {
            Max_Value = sum_value + value[index];
        }
        //load current thing to bag
        DFS_Bag(index + 1, sum_value + value[index], sum_volume + volume[index]);
    }
    
}
//DFS优化  放当前物品之前检验背包容量是否超过V
/*
void DFS_Bag(int index, int sum_value, int sum_volume)
{
    if (index == N)
    {
        if (sum_volume <= V&&sum_value > Max_Value)
        {
            Max_Value = sum_value;
            //cout << Max_Value<<endl;
        }
        return;
    }
    //not load current thing to bag
    DFS_Bag(index + 1, sum_value, sum_volume);
    //load current thing to bag
    DFS_Bag(index + 1, sum_value + value[index], sum_volume + volume[index]);
}*/

int main()
{
    int T;
    
    int i, j;
    cin >> T;
    while (T--)
    {
        cin >> N>>V;
        for (i = 0; i < N; i++)
        {
            cin >> volume[i];
            
        }
        for (i = 0; i < N; i++)
        {
            cin >> value[i];
        }
        DFS_Bag(0, 0, 0);
        cout << Max_Value << endl;
    }
    return 0;
}

DP解法:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
long long max(long long num1,long long num2)//比较函数
{
return num1>num2?num1:num2;
}
long long dp[1005][1005];//定义背包数组
int main()
{
    int t;//数据组数
    int m_bone,m_volume;
    int bone[1005], volume[1005];
    cin >> t;
    while (t--)
    {
        int i, j, k;
        memset(dp, 0, sizeof(dp));
        memset(bone,0,sizeof(bone));
        memset(volume, 0, sizeof(volume));
        cin >> m_bone >> m_volume;
        for (i = 1; i <= m_bone; i++)
            cin >> bone[i];
        for (j = 1; j <= m_bone; j++)
            cin >> volume[j];
        for (i = 1; i <= m_bone; i++)
        {
            for (j = 0; j <= m_volume; j++)
            {
                if (j < volume[i])
                {
                    dp[i][j] = dp[i - 1][j];
                    continue;
                }
                else
                {
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - volume[i]] + bone[i]);
                }
                
            }
        }
        cout << dp[m_bone][m_volume] << endl;
    }
    return 0;
}

 动态规划2:

#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
const int maxnum = 1005;
int N, V;
int Max_Value = 0;
int value[maxnum];
int volume[maxnum];
int dp[maxnum];
#define max(x,y)(x)>(y)?(x):(y);
//动态规划解
int  DP()
{
    int i, j;
    memset(dp, 0, sizeof(dp));
    for (i = 0; i < N; ++i)//N件物品
    {
        for (j = V; j>=volume[i]; --j)
        {
            dp[j] = max(dp[j - volume[i]] + value[i], dp[j]);//装入物品
        }
    }

    return dp[V];
    
}

int main()
{
    int T;
    
    int i, j;
    cin >> T;
    while (T--)
    {
        cin >> N>>V;
    
        for (i = 0; i < N; i++)
        {
            cin >> value[i];
        }
        for (i = 0; i < N; i++)
        {
            cin >> volume[i];

        }
        cout << DP() << endl;
    }
    return 0;
}

 dp3

#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
const int maxnum = 1005;
int N, V;
int Max_Value = 0;
int value[maxnum];
int volume[maxnum];
long long dp[maxnum][maxnum];
#define max(x,y)(x)>(y)?(x):(y);
void DP()
{
    int i, j;
    for (i = 1; i <= N; i++)
    {
        for (j = 0; j <= V; j++)//注意j从0开始
        {
            if (volume[i]>j)//如果装不下
            {
                dp[i][j] = dp[i-1][j];
            }
            else//能装下
            {
                if (dp[i - 1][j]>dp[i-1][j - volume[i]] + value[i])//不装价值大
                {
                    dp[i][j] = dp[i - 1][j];
                }
                else//前i-1个物品的最优解与第i个物品的价值之和更大
                {
                    dp[i][j] = dp[i-1][j - volume[i]] + value[i];
                }
            }
        }
    }
    
    cout << dp[N][V] << endl;
}

int main()
{
    int T;
    
    int i, j;
    cin >> T;
    while (T--)
    {
        cin >> N>>V;
    
        for (i = 1; i <= N; i++)
        {
            cin >> value[i];
        }
        for (i = 1; i <= N; i++)
        {
            cin >> volume[i];

        }
        DP();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/gcter/p/9850970.html