• P1021 邮票面值设计(dfs+背包dp)


    P1021 邮票面值设计

    题目传送门

    题意:

    给定一个信封,最多只允许粘贴N张邮票,计算在给定KN+K≤15N+K15)种邮票的情况下

    (假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX

    使在1至MAX之间的每一个邮资值都能得到。

    思路:

    dfs+背包dp

      暴搜k种邮票,下一种邮票的取值就是上一张邮票值+1,到上一次选的最大值+1;

       比如这上一次你选了1,n=3时,下一次你能选的就是2,3,4;

      然后怎么确定当前选择i之后的最大值呢,就是用到背包dp,dp[i]表示凑

      到i时所用的最少邮票数。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define N 105
    int n,k;
    int res;
    int ans[N],tmp[N],dp[2005];
    
    int get(int cur,int sum)
    {
        memset(dp,0x3f3f3f3f,sizeof(dp));
        dp[0]=0;
        for(int i=1;i<=cur;i++)
        {
            for(int j=tmp[i];j<=n*sum;j++)
                dp[j]=min(dp[j],dp[j-tmp[i]]+1);;
        }
        for(int i=1;i<=n*sum;i++)
            if(dp[i]>n) return i-1;
        return n*sum;
    }
    void dfs(int cur,int L1,int L2,int sum)
    {
        if(cur>k)
        {
            if(res<L2)
            {
                res=L2;
                for(int i=1;i<=n;i++)
                    ans[i]=tmp[i];
            }
            return ;
        }
        for(int i=L1+1;i<=L2+1;i++)
        {
            tmp[cur]=i;
            int x=get(cur,sum+i);
            dfs(cur+1,i,x,sum+i);
        }
    }
    int main()
    {
        while(~scanf("%d %d",&n,&k))
        {
            res=0;
            dfs(1,0,0,0);
            for(int i=1;i<=k;i++)
                printf("%d ",ans[i]);
            printf("
    MAX=");
            printf("%d
    ",res);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HDFS文件操作(基本文件命令)
    <a> 标签
    css text-overflow
    zepto.js 打包自定义模块
    CSS3 box-sizing
    CSS3 Filter
    JQ 导出 Excel
    outline css2
    iphone 操作手势种类
    动手写一个简单的Web框架(模板渲染)
  • 原文地址:https://www.cnblogs.com/zhgyki/p/10372178.html
Copyright © 2020-2023  润新知