洛谷 P2725 邮票 Stamps 解题报告

摘要:
P2725邮票的背景是一套N枚邮票的面值和上限K,这意味着可以在信封上粘贴K枚邮票。计算从1到M的最大连续邮资。例如,假设有1和3个邮票;你最多可以贴五张邮票。K是可用邮票的总数。第2行在文件末尾:N个整数,每行15个,列出所有N个邮票的面值,每个邮票的面值不得超过10000。y: x;}intdp[3000010];//表示合成面值为i intk,n,m_ max=0时使用的最小图章数;//邮票总数,面值intkind[52];intmain(){memset;scanf;对于{scanf;m_max=max;}dp[0]=0;对于{intr=m_max*k+1;fordp[j+kind[i]]=min;}forif{printf;break;}return0;}事实上,我没有想到最后把它放在数组中。
P2725 邮票 Stamps

题目背景

给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票。计算从 1 到 M 的最大连续可贴出的邮资。

题目描述

例如,假设有 1 分和 3 分的邮票;你最多可以贴 5 张邮票。很容易贴出 1 到 5 分的邮资(用 1 分邮票贴就行了),接下来的邮资也不难:

6 = 3 + 3 
7 = 3 + 3 + 1 
8 = 3 + 3 + 1 + 1 
9 = 3 + 3 + 3 
10 = 3 + 3 + 3 + 1 
11 = 3 + 3 + 3 + 1 + 1 
12 = 3 + 3 + 3 + 3 
13 = 3 + 3 + 3 + 3 + 1

然而,使用 5 枚 1 分或者 3 分的邮票根本不可能贴出 14 分的邮资。因此,对于这两种邮票的集合和上限 K=5,答案是 M=13。 [规模最大的一个点的时限是3s]

小提示:因为14贴不出来,所以最高上限是13而不是15

输入输出格式

输入格式:

第 1 行: 两个整数,K 和 N。K(1 <= K <= 200)是可用的邮票总数。N(1 <= N <= 50)是邮票面值的数量。

第 2 行 .. 文件末: N 个整数,每行 15 个,列出所有的 N 个邮票的面值,每张邮票的面值不超过 10000。

输出格式:

第 1 行:一个整数,从 1 分开始连续的可用集合中不多于 K 张邮票贴出的邮资数。


这是一个我一开始就想偏了的完全背包。

一开始:

#include <cstdio>
const int N=201;
const int inf=0x3f3f3f3f;
int max(int x,int y) {return x>y?x:y;}
int min(int x,int y) {return x>y?y:x;}
bool dp[3000010];//表示在第i张时面值k是否ok
int k,n;//邮票总数,面值数
int kind[52];
int m_min=inf,m_max=0;
int main()
{
    scanf("%d%d",&k,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",kind+i);
        m_max=max(kind[i],m_max);
        m_min=min(kind[i],m_min);
    }
    dp[0]=true;
    for(int i=0;i<k;i++)
    {
        int l=m_min*i,r=m_max*i;
        for(int p=r;p>=l;p--)
            if(dp[p])
                for(int j=1;j<=n;j++)
                    dp[p+kind[j]]=true;
    }
    for(int i=1;i<=m_max*k+1;i++)
    {
        if(!dp[i])
        {
            printf("%d
",i-1);
            break;
        }
    }
    return 0;
}

三维的呢。


完全背包:

#include <cstdio>
#include <cstring>
const int N=201;
const int inf=0x3f3f3f3f;
int max(int x,int y) {return x>y?x:y;}
int min(int x,int y) {return x>y?y:x;}
int dp[3000010];//表示在组成面值为i时用的最小邮票数
int k,n,m_max=0;//邮票总数,面值数
int kind[52];
int main()
{
    memset(dp,0x3f,sizeof(dp));
    scanf("%d%d",&k,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",kind+i);
        m_max=max(m_max,kind[i]);
    }
    dp[0]=0;
    for(int i=1;i<=n;i++)
    {
        int r=m_max*k+1;
        for(int j=0;j<=r;j++)
            dp[j+kind[i]]=min(dp[j+kind[i]],dp[j]+1);
    }
    for(int i=0;;i++)
        if(dp[i]>k)
        {
            printf("%d
",i-1);
            break;
        }
    return 0;
}

其实把(k)放在数组里面最后比,我还真没想到。

我所能理解的思维导向是从完全背包出发的。

每种邮票都有无限多张

注意常数优化,比如(j)的枚举显然并不是最优的


2018.5.3

免责声明:文章转载自《洛谷 P2725 邮票 Stamps 解题报告》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇DrawIO怎么画出卡通效果的?洛谷 P1450.硬币购物 解题报告下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

穷家富路

穷家富路_百度百科 穷家富路【名称】穷家富路【拼音】qióng jiā fù lù【解释】在家可节约开支,出门却宜多备盘缠。【出处】清·石玉昆《三侠五义》第23回:“银子虽多,贤弟只管拿去。俗语说得好:‘穷家富路。’”【事例】出外旅行要记住~的道理。【用法】作宾语、定语;指出门事宜[1]...

多层架构的调用方式(方法回调)

多层架构,一般我们指三层架构,如WEB层,SERVICE层和DATA,其实我是最简单的一种说法,真正的项目开发中,远远不只有这三层,其实在WEB与SERVICE层中还有一个WEB.SERVICE层,主要用来作WEB与SERVICE的服务,它与直接与前台VIEW通讯,也不直接与底层数据通讯,一般来说,都是用来做文件管理,上传,下载,COOKIES的持久化等,一...

对于百万条数据进行查询:自己对2万条数据进行的测试,答案是。。。

对于sqlserver处理百万条数据时,我们要注意了,一定要设index,如果不设那么速度会很慢的。 看我的吧: set ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER proc [dbo].[testTime] as declare @d datetime --define a variable of dateti...

NetBeans IDE 6.8 发布候选版 2 已经可用!

NetBeans 团队荣幸地宣布 NetBeans IDE 6.8 发布候选版 2 已经可用。 下载 NetBeans 6.8 发布候选版 2 关于 NetBeans 6.8 NetBeans 6.8 教程与视频 下载 NetBeans 6.8 RC2 并提交您的反馈,或者参与邮件列表与论坛 进行讨论。NetBeans IDE 6.8 正式...

Grub SplashImage

前一段时间在论坛上看到有文章谈到使用gfxboot来美化Grub启动界面,看着那些贴出的华丽界面,心里确实痒痒的,如是就按着文章里所说的下载相应的软件包来安装试验,也居然出来了效果,在前面的文章中记下了相关的方法步骤。然而好景不长,今天偶然间发现gfxboot居然不能启动我机子上的FreeBSD,命令都是一样的,配置也都是一样,就是起不来。心里郁闷,于是决定...

Shell编程(六)Here Documents与Dialog

Here Documents从一个Shell脚本传递给一个命令的一个比较特殊的方法就是使用here document.这个文档可以使得执行的命令就像是由文件或是键盘读入的,而事实上,这是由这个脚本读入的.一个here document是以<<开头的,后面所跟的是要在文档的结尾处重复出现的字符序列.<<是Shell的重定向标签,在这样的...