洛谷P2732 商店购物 Shopping Offers
P2732 商店购物 Shopping Offers
- 23通过
- 41提交
- 题目提供者该用户不存在
- 标签USACO
- 难度提高+/省选-
提交 讨论 题解
最新讨论
- 暂时没有讨论
题目背景
在商店中,每一种商品都有一个价格(用整数表示)。例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z 。为了吸引更多的顾客,商店举行了促销活动。
题目描述
促销活动把一个或多个商品组合起来降价销售,例如:
三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是 12z。 编写一个程序,计算顾客购买一定商品的花费,尽量利用优惠使花费最少。尽管有时候添加其他商品可以获得更少的花费,但是你不能这么做。
对于上面的商品信息,购买三朵花和两个花瓶的最少花费的方案是:以优惠价购买两个花瓶和一朵花(10z),以原价购买两朵花(4z)。
输入输出格式
输入格式:
输入文件包括一些商店提供的优惠信息,接着是购物清单。(最多有5种商品)
第一行 优惠方案的种类数(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 个商品。
输出格式:
只有一行,输出一个整数:购买这些物品的最低价格。
输入输出样例
2
1 7 3 5
2 7 1 8 2 10
2
7 3 2
8 2 5
14
说明
题目翻译来自NOCOW。
USACO Training Section 3.3
分析:这道题和斗地主很像,目的就是要把所有的物品买完,也就相当于把牌出完,给你几种优惠方式相当于牌的组合,让我不禁联想到了noip2015斗地主,我们可以搜索每一种优惠方式能不能行,如果可以就继续,不行就搜索下一种优惠方式,如果都不行,那么就只能一个一个的买了,为了避免重复,用了一个hash,但是这样还是超时了.听raffica神犇说如果倒着输入会有惊喜,然后发现,还是T了5个点,只能想其他的办法.
发现搜索是从已知状态扩展到未知状态,如果是用已知状态来更新未知状态呢?这就是dp了,枚举优惠方式,如果可行,则根据优惠方式所需的物品来推得当前的状态,f[a][b][c][d][e] = f[a - i][b - j][c - k][d - l][e - m] + p,i,j,k,l,m都是所需的物品,p是钱数,这其实就是完全背包.
49分代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int s,b,vis1[],need[],neednum[],needmoney[],ans = ,vis[][][][][],hashh[],tot; struct node
{
int num[];
int money;
}a[]; void dfs(int m,int n)
{
int flag = ;
for (int i = ; i <= n; i++)
{
//printf("%d\n", neednum[need[i]]);
if (neednum[need[i]] != )
{
flag = ;
break;
}
}
if (flag == )
if (ans > m)
{
ans = m;
return;
}
if (hashh[vis[neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]]] != && hashh[vis[neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]]] == m)
return;
vis[neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]] = ++tot;
hashh[vis[neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]][neednum[need[]]]] = m;
for (int i = ; i <= s; i++)
{
int flag1 = ;
for (int j = ; j <= n; j++)
if (neednum[need[j]] < a[i].num[need[j]])
{
flag1 = ;
break;
}
if (flag1 == )
{
//printf("%d\n", i);
for (int j = ; j <= n; j++)
neednum[need[j]] -= a[i].num[need[j]];
dfs(m + a[i].money, n);
for (int j = ; j <= n; j++)
neednum[need[j]] += a[i].num[need[j]];
}
}
for (int i = ; i <= n; i++)
if (neednum[need[i]] >= )
{
neednum[need[i]]--;
dfs(m + needmoney[need[i]], n);
neednum[need[i]]++;
}
return;
} int main()
{
scanf("%d", &s);
for (int i = s; i >= ; i--)
{
int n,t = ,p;
scanf("%d", &n);
for (int j = ; j <= n; j++)
{
int k, c;
scanf("%d%d", &c, &k);
a[i].num[c] = k;
}
scanf("%d", &p);
a[i].money = p;
}
scanf("%d", &b);
int t = ;
for (int i = ; i <= b; i++)
{
int c, k, p;
scanf("%d%d%d", &c, &k, &p);
if (!vis1[c])
{
vis1[c] = ;
need[++t] = c;
}
neednum[c] = k;
needmoney[c] = p;
}
/*
for (int i = 1; i <= s; i++)
{
for (int j = 1; j <= t; j++)
printf("%d需要%d\n", need[j], a[i].num[need[j]]);
printf("钱%d\n", a[i].money);
}
for (int i = 1; i <= t; i++)
printf("%d %d %d\n", need[i], neednum[need[i]], needmoney[need[i]]);
*/
dfs(,t);
printf("%d\n", ans);
//while (1); return ;
}
AC代码(显然不是我的):
#include<cstdio>
#include<iostream>
#include<algorithm>
int n;
int i, j, k, l, m, z;
struct haha
{
int n;
int k[];
int p;
}a[];
int nn;
int d[];
int t;
int ai, bi, ci;
int f[][][][][];
int x[];
using namespace std;
int main()
{
scanf("%d", &n);
for (i = ;i <= n;i++)
{
scanf("%d", &a[i].n);
for (j = ;j <= a[i].n;j++)
{
scanf("%d%d", &ai, &bi);
if (d[ai] == )
{
t++;
d[ai] = t;
}
a[i].k[d[ai]] = bi;
}
scanf("%d", &a[i].p);
}
scanf("%d", &nn);
for (i = ;i <= nn;i++)
{
scanf("%d%d%d", &ai, &bi, &ci);
if (d[ai] == )
{
t++;
d[ai] = t;
}
x[d[ai]] = bi;
n++;
a[n].n = ;
a[n].k[d[ai]] = ;
a[n].p = ci;
}
for (i = ;i <= ;i++)
for (j = ;j <= ;j++)
for (k = ;k <= ;k++)
for (l = ;l <= ;l++)
for (m = ;m <= ;m++)
f[i][j][k][l][m] = ;
f[][][][][] = ;
for (z = ;z <= n;z++)
for (i = a[z].k[];i <= x[];i++)
for (j = a[z].k[];j <= x[];j++)
for (k = a[z].k[];k <= x[];k++)
for (l = a[z].k[];l <= x[];l++)
for (m = a[z].k[];m <= x[];m++)
f[i][j][k][l][m] = min(f[i][j][k][l][m],f[i - a[z].k[]][j - a[z].k[]][k - a[z].k[]][l - a[z].k[]][m - a[z].k[]]+ a[z].p);
printf("%d\n", f[x[]][x[]][x[]][x[]][x[]]);
return ;
}
洛谷P2732 商店购物 Shopping Offers的更多相关文章
- USACO Section 3.3 商店购物 Shopping Offers
题目背景 在商店中,每一种商品都有一个价格(用整数表示).例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z .为了吸引更多的顾客,商店举行了促销活动. 题目描述 促销活动把 ...
- 商店购物 (shopping.c/cpp/pas)
1.商店购物 (shopping.c/cpp/pas) 在滨海市开着 n 家商店,编号依次为 1 到 n,其中编号为 1 到 m 的商店有日消费量上 限,第 i 家商店的日消费量上限为 wi. 海霸王 ...
- 洛谷 P1450.硬币购物 解题报告
P1450.硬币购物 题目描述 硬币购物一共有\(4\)种硬币.面值分别为\(c1,c2,c3,c4\).某人去商店买东西,去了\(tot\)次.每次带\(d_i\)枚\(c_i\)硬币,买\(s_i ...
- 洛谷P1450.硬币购物
传送门 题目大意:4种面值c[i]的硬币,每种硬币持有d[i]个,问有多少种方法支付出正好N块钱. 可以先预处理出持有硬币无限的情况dp[n],即一个完全背包问题. 之后根据容斥原理,相当于求但是拥有 ...
- 【洛谷】P4585 [FJOI2015]火星商店问题
题解 题目太丧,OJ太没有良心,我永远喜欢LOJ! (TLE报成RE,垃圾洛谷,我永远喜欢LOJ) 好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解 把所有限制去掉,给出一个值, ...
- 洛谷P1450 [HAOI2008]硬币购物(背包问题,容斥原理)
洛谷题目传送门 我实在是太弱了,第一次正儿八经写背包DP,第一次领会如此巧妙的容斥原理的应用...... 对每次询问都做一遍多重背包,显然T飞,就不考虑了 关键就在于每次询问如何利用重复的信息 我这么 ...
- 洛谷P1064 金明的预算方案
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...
- 洛谷P1171 售货员的难题
P1171 售货员的难题 题目背景 数据有更改 题目描述 某乡有n个村庄(1<n<20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且 ...
- 【Bzoj2260】【Bzoj4349】商店购物 & 最小树形图
目录 List Bzoj 2260 商店购物 Description Input Output Sample Input Sample Output Bzoj 4349 最小树形图 Descripti ...
随机推荐
- Linux环境变量文件environment, profile, bashrc含义
转自:http://www.th7.cn/system/lin/201508/127503.shtml (1)/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件 ...
- PHP Socket 编程详解
PHP中的实现 服务端 <?php set_time_limit(0); // 设置主机和端口 $host = "127.0.0.1"; $port = 12387; // ...
- css设置背景图片,ie显示不了
本来是想给导航栏<div class="nav"></div>添加背景图片的,设置css样式如下: .nav{background:url("ht ...
- scala高级内容(二) - Implicit
一. Implicit关键字 隐士转换 (1)隐士转换函数:用implicit修饰的,只有一个参数的函数.他会被自动执行,来把一个值转换成另一个 class RichFile(val f:File){ ...
- CMake使用教程
转自 RichardXG 原文 CMake使用教程 CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目. 通过编写CMak ...
- 加入ScrollView后OnGestureListener无效的解决办法
android中,ViewFlipper+OnGestureListener可以实现左右滑动效果. 但是在ViewFlipper加上了ScrollView就悲剧了,左右滑动事件无效了…… 这里其实只需 ...
- 转--Android实现ListView过滤功能,继承于BaseAdapter,非ArrayAdapter。
其实实现ListView过滤功能最方便的便是使用ArrayAdapter,里面自带的getFilter()方法能很方便的实现此功能,但是在实际的开发中,一般都是继承于BaseAdapter.还有一种是 ...
- sqlite 时间排序
select * from tb_QuantifyResult where iSamplingOrCalibration = 1 and cComponentName <> ' + Quo ...
- C#局域网聊天工具_UDP广播
接上一讲,程序启动就要发送广播消息,如何发送广播消息,这一讲将给大家好好讲讲网络广播的知识,以及C#如何实现广播. 第一部分.什么是广播地址,以及广播地址怎么计算 1.1 广播地址是什么? 主机号全为 ...
- java类的高级特性
1.非内部类不能被声明为private 或protected访问类型.