[zoj]1013

题意:给出n种装载东西的信息(w,s)  3物品(w,s,d)  3种物品组合(c1,c2,c3,d)求出最大的防御值

思路:一看题目就有种背包的想法,但是此题有个信息就是如果知道三种物品的各自的数量,那么防御值就很简单的求了出来

        用f[i][j][k]表示前i辆车装j第一件物品k第二件物品时 第三件物品最多能装的个数

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int n, c1, c2, c3, d4;
int w[4], s[4], d[4];
int cw[105], cs[105], f[2][505][505];

int main()
{
    int cas = 0;
    while(scanf("%d",&n) && n)
    {
        for(int i = 1 ; i <= 3 ; i++)
            scanf("%d%d%d",&w[i],&s[i],&d[i]);
        scanf("%d%d%d%d",&c1,&c2,&c3,&d4);
        for(int i = 1 ; i <= n ; i++)
            scanf("%d%d",&cw[i],&cs[i]);
        memset(f,-1,sizeof(f));
        f[0][0][0] = 0;
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = 0 ; j <= min(cw[i]/w[1],cs[i]/s[1]) ; j++)
            {
                for(int k = 0 ; k <= min(cw[i]/w[2],cs[i]/s[2]) ; k++)
                {
                    if(j*w[1]+k*w[2] > cw[i] || j*s[1]+k*s[2] > cs[i])
                    {
                        break;
                    }
                    else
                    {
                        for(int p = 0 ; p < 505 ; p++)
                        {
                            for(int q = 0 ; q < 505 ; q++)
                            {
                                if(f[(i-1)%2][p][q] == -1)
                                {
                                    continue;
                                }
                                else
                                {
                                    int cmp = f[(i-1)%2][p][q]+min((cw[i]-j*w[1]-k*w[2])/w[3],(cs[i]-j*s[1]-k*s[2])/s[3]);
                                    if(f[i%2][p+j][q+k] < cmp)
                                        f[i%2][p+j][q+k] = cmp;
                                }
                            }
                        }
                    }
                }
            }
        }
        int res = -1;
        for(int i = 0 ; i < 505 ; i++)
        {
            for(int j = 0 ; j < 505 ; j++)
            {
                if(f[n%2][i][j] == -1)
                {
                    continue;
                }
                else
                {
                    if(d[1]+d[2]+d[3] >= d4)
                    {
                        if(res < f[n%2][i][j]*d[3]+i*d[1]+j*d[2])
                            res = f[n%2][i][j]*d[3]+i*d[1]+j*d[2];
                    }
                    else
                    {
                        int con = min(f[n%2][i][j]/c3,min(i/c1,j/c2));
                        int ress = con*d4+(i-con*c1)*d[1]+(j-con*c2)*d[2]+(f[n%2][i][j]-con*c3)*d[3];
                        res = res<ress?ress:res;
                    }
                }
            }
        }
        if(cas > 0)
            printf("\n");
        printf("Case %d: %d\n",++cas,res);
    }
    return 0;
}

转载于:https://www.cnblogs.com/zuckerTT/archive/2012/05/12/2497288.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值