首页 > 其他 > 详细

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

时间:2019-02-13 23:13:03      阅读:561      评论:0      收藏:0      [点我收藏+]

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("\nMAX=");
        printf("%d\n",res);
    }
    return 0;
}
View Code

 

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

原文:https://www.cnblogs.com/zhgyki/p/10372178.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!