SHUOJ小偷偷东西

最近由于刚开学事情很多所以久不更新(你看这个借口起得多好),再经过一番思想斗争后终于开始认真学习,希望以后博客能高产似母猪。

描述

一天晚上,小偷带了一个包偷偷进入一家人家。小偷发现那人家家里东西很多,但他看中了n个物品,这n个物品的第i个的体积为wi,价值为vi(i=1,2,……,n),包能容纳的物品的体积为c,他要从这n个物品中选出若干件放入包,使得放入包内的物品的总体积不超过c,而总价值达到最大。

输入
输入有若干组测试数据(不超过20组)。

每组测试数据有3行:其第1行上有2个整数n和c,分别是物品个数n和包所能容纳物品的体积,(n<=50,c<=500),第2行上有n个整数v1、v2、…、vn,依次是n个物品的价值,第3行上有n个整数w1、w2、…、wn,,分别是n个物品的重量。诸整数之间用一个空格分开。

输出
现对输入中的每组测试数据,输出1行:先输出“Case #:”,其中“#”是测试数据的组号(从1开始)。接着输出包能装的物品的最大价值。

我的想法

动态规划中的背包问题,在网上随便搜一搜就能找到一大堆资料、讲解和拓展。
在本题中最关键的就是这个公式

f[i,j]=Maxf[i1,jW[i]]+Pi,f[i1,j]

即在已装i-1个将要装第i个物体时,若能装下则取使价值最大的方法,若装不下则不装(保持相同的值)。
唯一在实际代码中困扰我许久的问题是变量的初始化。刚用c++,初始化什么的不太理解常常编译错误和出现莫名其妙的值。最后还是用for统一赋了一遍,希望能有所改进。

AC代码

#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
    int n,v,k=1;
    while(scanf("%d %d",&n,&v)==2)  //物体总数和体积上限
    {
        int w[n+1],val[n+1];  //单个物体的体积和价值
        w[0]=val[0]=0;
        int i,j;
        for(i=1;i<=n;i++)
            cin>>val[i];
        for(i=1;i<=n;i++)
            cin>>w[i];
        int a[n+1][v+1];
        for(i=0;i<=n;i++)
            for(j=0;j<=v;j++)
            a[i][j]=0;
        for(i=1;i<=n;i++)
        {
            for(j=v;j>=0;j--)    //逆序
            {
                if(w[i]<=j)
                {
                    a[i][j]=a[i-1][j]>(a[i-1][j-w[i]]+val[i])?a[i-1][j]:a[i-1][j-w[i]]+val[i];
                }
                else
                    a[i][j]=a[i-1][j];
            }
        }
        cout<<"Case "<<k<<":"<<a[n][v]<<endl;
        k++;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/waveviewer/article/details/78006839