Hrbust 2099/Poj 1170 Shopping Offers【离散化+Dp】

Shopping Offers
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 5114 Accepted: 2138

Description


In a shop each kind of product has a price. For example, the price of a flower is 2 ICU (Informatics Currency Units) and the price of a vase is 5 ICU. In order to attract more customers, the shop introduces some special offers. 
A special offer consists of one or more product items for a reduced price. Examples: three flowers for 5 ICU instead of 6, or two vases together with one flower for 10 ICU instead of 12. 
Write a program that calculates the price a customer has to pay for certain items, making optimal use of the special offers. That is, the price should be as low as possible. You are not allowed to add items, even if that would lower the price. 
For the prices and offers given above, the (lowest) price for three flowers and two vases is 14 ICU: two vases and one flower for the reduced price of 10 ICU and two flowers for the regular price of 4 ICU. 

Input

Your program is to read from standard input. The first line contains the number b of different kinds of products in the basket (0 <= b <= 5). Each of the next b lines contains three values c, k, and p. The value c is the (unique) product code (1 <= c <= 999). The value k indicates how many items of this product are in the basket (1 <= k <= 5). The value p is the regular price per item (1 <= p <= 999). Notice that all together at most 5*5=25 items can be in the basket. The b+2nd line contains the number s of special offers (0 <= s <= 99). Each of the next s lines describes one offer by giving its structure and its reduced price. The first number n on such a line is the number of different kinds of products that are part of the offer (1 <= n <= 5). The next n pairs of numbers (c,k) indicate that k items (1 <= k <= 5) with product code c (1 <= c <= 999) are involved in the offer. The last number p on the line stands for the reduced price (1 <= p <= 9999). The reduced price of an offer is less than the sum of the regular prices.

Output

Your program is to write to standard output. Output one line with the lowest possible price to be paid.

Sample Input

2
7 3 2
8 2 5
2
1 7 3 5
2 7 1 8 2 10

Sample Output

14

Source


题目大意:

有N个物品,每个物品三个元素:商品号,商品个数,每个物品的单价。

有M个组合,每个组合首先输入一个数Mi表示这个组合要有多少个物品参与进来,接下来Mi对数(C,K)表示商品号为C的物品有K个.最后一个数表示一起这样购买这Mi组物品的价格会变成的价值val.

问将N个物品都购买了,最小花费是多少。


思路:


题目不难,首先观察到数据范围都不大,那么我们考虑暴力dp,首先将物品按照编号离散化一下。

然后:

设定Dp【i】【j】【k】【l】【z】表示第1种物品购买了i个,第2种物品购买了j个,第3种物品购买了k,个第4种物品购买了l个,第5种物品购买了z个的最小花费。

那么状态转移方程我们有:
这里del【x】【j】表示第x种促销方式中,第j种物品需要购买的数量。



注意一些细节以及数组越界以及初始化的问题即可。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<map>
using namespace std;
struct node
{
    int pos,num,val;
}a[10];
int del[150][15];
int delval[100];
int dp[7][7][7][7][7];
int n,m;
void init()
{
    memset(dp,0,sizeof(dp));
    memset(delval,0,sizeof(delval));
    memset(del,0,sizeof(del));
    memset(a,0,sizeof(a));
    map<int ,int >s;
    int tot=0;
    for(int i=1; i<=n; i++)
    {
        int p,num,val;
        scanf("%d%d%d",&p,&num,&val);
        if(s[p]==0)++tot,s[p]=tot;
        a[i].pos=s[p],a[i].num=num,a[i].val=val;
    }
    scanf("%d",&m);
    for(int j=1; j<=m; j++)
    {
        int len;scanf("%d",&len);
        for(int k=1; k<=len; k++)
        {
            int x,num;
            scanf("%d%d",&x,&num);
            del[j][s[x]]+=num;
        }
        scanf("%d",&delval[j]);
    }
    for(int i=0;i<=5;i++)
    {
        for(int j=0;j<=5;j++)
        {
            for(int k=0;k<=5;k++)
            {
                for(int l=0;l<=5;l++)
                {
                    for(int z=0;z<=5;z++)
                    {
                        dp[i][j][k][l][z]=0x3f3f3f3f;
                    }
                }
            }
        }
    }
    dp[0][0][0][0][0]=0;
}
int main()
{
    while(~scanf("%d",&n))
    {
        init();
        for(int i=0;i<=5;i++)
        {
            for(int j=0;j<=5;j++)
            {
                for(int k=0;k<=5;k++)
                {
                    for(int l=0;l<=5;l++)
                    {
                        for(int z=0;z<=5;z++)
                        {
                            if(i-1>=0)dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i-1][j][k][l][z]+a[1].val);
                            if(j-1>=0)dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i][j-1][k][l][z]+a[2].val);
                            if(k-1>=0)dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i][j][k-1][l][z]+a[3].val);
                            if(l-1>=0)dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i][j][k][l-1][z]+a[4].val);
                            if(z-1>=0)dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i][j][k][l][z-1]+a[5].val);
                            for(int x=1;x<=m;x++)
                            {
                                if(i>=del[x][1]&&j>=del[x][2]&&k>=del[x][3]&&l>=del[x][4]&&z>=del[x][5])
                                dp[i][j][k][l][z]=min(dp[i][j][k][l][z],dp[i-del[x][1]][j-del[x][2]][k-del[x][3]][l-del[x][4]][z-del[x][5]]+delval[x]);
                            }
                        }
                    }
                }
            }
        }
        printf("%d\n",dp[a[1].num][a[2].num][a[3].num][a[4].num][a[5].num]);
    }
}




源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值