• COJ 1086: 超市购物 (背包问题)


    Description

            上次去超市扫荡回来的东西用完了,Staginner又得跑超市一趟,出发前他列了一张购物清单,打算去买K种不同的商品,每种买一件。到了超市,Staginner发现每种商品有N个品牌,每个品牌此商品的价格为Vi,对Staginner的作用值为Wi,他会从这N个品牌里面挑一个品牌买。这时,Staginner突然想起出门时只带了M元钱,又懒得去取钱了,所以不一定能买完K种商品,只好尽可能地让买的东西对自己的总作用值ans最大。

    Input

     多组样例。

        第一行两个整数K,M代表Staginner想买的不同种类商品的数目和他带的钱 (0 < K <= 30, 0 < M <= 2000)
        以下输入分为K个部分,代表K种商品。
        每个部分第一行为一个数字N,代表第k种商品的N个品牌,N不大于10。之后跟着N行,每行两个数字,代表物品的价格Vi和作用值Wi。其中 0 < Vi < M。

    Output

     输出Case #: 最大总作用值,每两个样例之间有一个空行。

    Sample Input

    3 100
    3
    50 600
    20 700
    30 800		
    2
    30 500
    40 600	
    1
    60 200
    
    2 500
    2
    200 1000
    260 1200
    1
    280 300

    Sample Output

    Case 1: 1400
    
    Case 2: 1300

    分组背包问题。

    View Code
    #include <stdio.h>
    #include <string.h>
    #define K 30
    #define N 10
    #define M 2001
    int k,m;
    int cnt[K];
    int w[K][N],v[K][N];
    int d[M][K][N];
    int dp(int money,int i,int j)
    {
        if(d[money][i][j]!=-1)  return d[money][i][j];
        if(money==0)    return d[money][i][j]=0;
        if(i==0 && j==0)
        {
            if(money>=v[i][j])   return d[money][i][j]=w[i][j];
            return d[money][i][j]=0;
        }
        if(i==0)
        {
            if(money>=v[i][j] && w[i][j]>=dp(money,i,j-1))   return d[money][i][j]=w[i][j];
            return d[money][i][j]=dp(money,i,j-1);
        }
        if(j==0)
        {
            if(money>=v[i][j] && dp(money-v[i][j],i-1,cnt[i-1]-1)+w[i][j]>dp(money,i-1,cnt[i-1]-1))
                return d[money][i][j]=dp(money-v[i][j],i-1,cnt[i-1]-1)+w[i][j];
            return d[money][i][j]=dp(money,i-1,cnt[i-1]-1);
        }
        if(money>=v[i][j] && dp(money-v[i][j],i-1,cnt[i-1]-1)+w[i][j]>dp(money,i,j-1))
            return d[money][i][j]=dp(money-v[i][j],i-1,cnt[i-1]-1)+w[i][j];
        return d[money][i][j]=dp(money,i,j-1);
    }
    int main()
    {
        int i,j,kase=0;
        while(~scanf("%d%d",&k,&m))
        {
            for(i=0;i<k;i++)
            {
                scanf("%d",&cnt[i]);
                for(j=0;j<cnt[i];j++)
                {
                    scanf("%d%d",&v[i][j],&w[i][j]);
                }
            }
            memset(d,-1,sizeof(d));
            if(kase)    puts("");
            printf("Case %d: %d\n",++kase,dp(m,k-1,cnt[k-1]-1));
        }
        return 0;
    }
  • 相关阅读:
    Net设计模式实例之适配器模式(Adapter Pattern)
    Net设计模式实例之单例模式( Singleton Pattern)
    Net设计模式实例之原型模式( Prototype Pattern)
    20个非常棒的Jquery实用工具
    Net设计模式实例之备忘录模式(Memento Pattern)
    10个免费的javascript富文本编辑器(jQuery and nonjQuery)
    <推荐>65个以自然风光为背景的UI设计
    Net设计模式实例之代理模式(Proxy Pattern)
    UML建模之状态图(Statechart Diagram)
    13个绚丽的Jquery 界面设计
  • 原文地址:https://www.cnblogs.com/algorithms/p/2605768.html
Copyright © 2020-2023  润新知