hrbust 1558 小背包(简单01背包)水坑

小背包
Time Limit: 1000 MS Memory Limit: 10240 K
Total Submit: 1220(237 users) Total Accepted: 307(208 users) Rating: Special Judge: No
Description
有一个容量为m(1<=m<=4000000)的背包,有n(1<=n<=16)个物品,每个物品有体积v(1<=v<=2012)和价值w(0<=2012),现在要你选择一些物品,使得背包所装物品的总价值最大。

Input
有多组测试数据,但是不会超过10组。

对于每组测试数据,第一行是两个整数m和n,表示背包容量的和物品个数。接下来有n行,每行有两个整数,表示一个物品的体积和价值。

输入到文件结束。

Output
对于每组测试数据,输出一行,包含一个整数,为背包能装下物品的最大价值。

Sample Input
10 3
6 9
5 5
5 5
3 2
1 2
2 1
Sample Output
10
3
过程都只是一个普通的小背包,注意坑点在最大容积,第一眼看,可能觉得一定会超时爆内存,结果再往后面看发现只有16个物品,再往后看,每个物品最大只有2012,也就是说总重不会超过16*2012,背包容积最大值远大于物品体积,此时,dp数组只用设到33000左右就好,但为防止m过大,毕竟是要这个数据带入进去遍历dp数组的,所以即使没装那么多,也会遍历数组遍历到爆,RE就不可避免了。于是多加个判定条件,当容积远远大于所有物品体积时,直接全部装进去就好了,不用再执行后面的算法。这样也是有道理的,毕竟你数组就是最大体积了,容积再大,也是都可以装进去的了,不仅省时还能避免数组越界

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[20][34000];///好坑啊,题目说了背包那么大,但是实际16个物品每个物品2012的体积,根本用不了那么大
struct box
{
    int cost;
    int value;
}num[20];
int main()
{
    int i,j,n,m;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        int sum=0,sum2=0;
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&num[i].cost,&num[i].value);
            sum=sum+num[i].cost;
            sum2=sum2+num[i].value;
        }
        if(sum<m)///注意自己输入的是m,即使合在一起的体积没那么大,容积还是会在遍历时用到m的数值,而发生数组越界,因此注意
        {
            printf("%d\n",sum2);///当输入的容积大于总体积时,可以直接输出所有的价值和,不用一个一个装上去了
            continue;
        }
        for(i=num[1].cost;i<=m;i++)
        {
            dp[1][i]=num[1].value;
        }
        for(i=2;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(j>=num[i].cost)
                {
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-num[i].cost]+num[i].value);///记住啊,容积减掉当前遍历的那个物品的体积,个数也要减掉一个诶
                }
                else
                    dp[i][j]=dp[i-1][j];///是物品-1,不是容积-1,是如果装不了,那就继承上面那个物品的在此容积下的价值!!!
            }
        }
//        for(i=0;i<=n;i++)///动态规划表超美的
//        {
//            for(j=0;j<=m;j++)
//            {
//                printf(" %d",dp[i][j]);
//            }
//            printf("\n");
//        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}
posted @ 2017-03-19 16:06  KuroNekonano  阅读(84)  评论(0编辑  收藏  举报