【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 108434
  • 排名 - 229

最新评论

阅读排行榜

评论排行榜

在商店中,每一种商品都有一个价格(用整数表示)。例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z 。为了吸引更多的顾客,商店举行了促销活动。

促销活动把一个或多个商品组合起来降价销售,例如:

三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是 12z。 编写一个程序,计算顾客购买一定商品的花费,尽量利用优惠使花费最少。尽管有时候添加其他商品可以获得更少的花费,但是你不能这么做。

对于上面的商品信息,购买三朵花和两个花瓶的最少花费是:以优惠价购买两个花瓶和一朵花(10z),以原价购买两朵花(4z)。

格式
PROGRAM NAME: shopping

INPUT FORMAT:(file shopping.in)

输入文件包括一些商店提供的优惠信息,接着是购物清单。

第一行 优惠商品的种类数(0 <= s <= 99)。

第二行..第s+1 行 每一行都用几个整数来表示一种优惠方式。第一个整数 n (1 <= n <= 5),表示这种优惠方式由 n 种商品组成。后面 n 对整数 c 和 k 表示 k (1 <= k <= 5)个编号为 c (1 <= c <= 999)的商品共同构成这种优惠,最后的整数 p 表示这种优惠的优惠价(1 <= p <= 9999)。优惠价总是比原价低。

第 s+2 行 这一行有一个整数 b (0 <= b <= 5),表示需要购买 b 种不同的商品。

第 s+3 行..第 s+b+2 行 这 b 行中的每一行包括三个整数:c ,k ,和 p 。 C 表示唯一的商品编号(1 <= c <= 999),k 表示需要购买的 c 商品的数量(1 <= k <= 5)。p 表示 c 商品的原价(1 <= p <= 999)。最多购买 5*5=25 个商品。

OUTPUT FORMAT:(file shopping.out)

只有一行,输出一个整数:购买这些物品的最低价格。

SAMPLE INPUT
2
1 7 3 5
2 7 1 8 2 10
2
7 3 2
8 2 5

SAMPLE OUTPUT
14

分析:
   0 <= b <= 5,1 <= k <= 5,可用5*5*5*5*5的DP 每种买0~5个,可以用6进制表示,然后5维DP~OK!

   状态设置:F[a1][a2][a3][a4][a5]为买a1件物品1,a2件物品2,a3件物品3,a4件物品4,a5件物品5时,所需的最少价格

边界条件:F[0][0][0][0][0]=0;

状态转移方程:
       F[a1][a2][a3][a4][a5]=min{F[ a1-P[i][1] ][ a2-P[i][2] ][ a3-P[i][3] ][ a4-P[i][4] ][ a5-P[i][5] ]+P[i][0])}
其中i=1..s+b; 且 ak-p[i][k]>=0

【参考程序】:

/*
ID: XIONGNA1
PROG: shopping
LANG: C++
*/
#include
<iostream>
#include
<cstring>
using namespace std;
int v[6],w[6],c[6],lz[100],hz[100][6];
int mz[100][6],z[100][6],ys[100];
int f[6][6][6][6][6];
bool ok[100];
int n,m;
int Find(int now)
{
    
for (int i=1;i<=m;i++)
        
if (v[i]==now) return i;
    
return 0;
}
int main()
{
    freopen(
"shopping.in","r",stdin);
    freopen(
"shopping.out","w",stdout);
    scanf(
"%d",&n);
    
for (int i=1;i<=n;i++)
    {
        scanf(
"%d",&lz[i]);
        
for (int j=1;j<=lz[i];j++)
            scanf(
"%d%d",&hz[i][j],&mz[i][j]);
        scanf(
"%d",&ys[i]);
    }
    scanf(
"%d",&m);
    
for (int i=1;i<=m;i++)
        scanf(
"%d%d%d",&v[i],&w[i],&c[i]);
    memset(ok,
true,sizeof(ok));
    
int x,y,pos;
    
for (int i=1;i<=n;i++)
    {
        
for (int j=1;j<=lz[i];j++)
        {
            x
=hz[i][j]; y=mz[i][j];
            pos
=Find(x);
            
if (pos==0) ok[pos]=false;
            
if (ok[pos]) z[i][pos]=y;
        }
    }
    
for (int i1=0;i1<=w[1];i1++)
        
for (int i2=0;i2<=w[2];i2++)
            
for (int i3=0;i3<=w[3];i3++)
                
for (int i4=0;i4<=w[4];i4++)
                    
for (int i5=0;i5<=w[5];i5++)
                        f[i1][i2][i3][i4][i5]
=i1*c[1]+i2*c[2]+i3*c[3]+i4*c[4]+i5*c[5];
    
for (int i=1;i<=n;i++)
        
if (ok[i])
            
for (int i1=z[i][1];i1<=w[1];i1++)
                
for (int i2=z[i][2];i2<=w[2];i2++)
                    
for (int i3=z[i][3];i3<=w[3];i3++)
                        
for (int i4=z[i][4];i4<=w[4];i4++)
                            
for (int i5=z[i][5];i5<=w[5];i5++)
                                
if (f[i1][i2][i3][i4][i5]>f[i1-z[i][1]][i2-z[i][2]][i3-z[i][3]][i4-z[i][4]][i5-z[i][5]]+ys[i])
                                    f[i1][i2][i3][i4][i5]
=f[i1-z[i][1]][i2-z[i][2]][i3-z[i][3]][i4-z[i][4]][i5-z[i][5]]+ys[i];
    printf(
"%d\n",f[w[1]][w[2]][w[3]][w[4]][w[5]]);                            
    
return 0;
}
posted on 2009-07-26 09:03 开拓者 阅读(243) 评论(0)  编辑 收藏 引用 所属分类: USACO 题解

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理