5464: 学习之取得小姐姐芳心 (01背包问题)

描述

爱上你的第一个夏天,我就想给你全世界。

我的小姐姐遇到了一个和十分严肃的问题快把她这个处女座给逼疯了,她现在让我帮她解决,当然菜鸡BobHuang是不会的,还是交给你吧。

他收集了很多叶脉书签,有桂花叶、石楠叶、木瓜叶、桉枝叶、茶树叶、玉兰叶等。每种书签都有一个漂亮值ai,而且她拥有这些书签的数量是一定的。现在她要给闺蜜送一个漂亮值正好为luck的书签集,她将把它打包邮寄给闺蜜,她还想选择最少的叶子以便闺蜜得到好看的叶子更多。

输出哪种书签要几个是小姐姐的问题,为了简化问题,BobHuang决定只让你输出最少的叶子数(题目保证答案一定存在)。

输入

输入数据有多组,输入到文件结束为止(少于30组)。

第一行为他拥有的书签种类n和需要书签集的漂亮值luck。(1<n<=12,0<luck<=105

接下来有n行,每行有两个数据,ai和numi,ai为这个树叶的漂亮值,numi为小姐姐拥有的这种书签数目(0<ai<109,1<numi<102

输出

每组样例输出为一个整数,代表正好为luck的最小叶子数。

样例输入

2 10
1 15
2 5
6 38
1 1
3 1
5 1
7 1
9 1
13 1

样例输出

5
6

思路:转换成01背包;

luck值就是背包中的背包容量,看注释吧

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i,n,j,m,v[1210],w[1210];
    int dp[100005];
    while(cin>>n>>m)
    {
        int k=1;
        memset(dp,0x3f3f3f3f,sizeof(dp));//因为求的是要刚好luck 所以这样初始化
        dp[0]=0;
        for(i=1;i<=n;i++)
        {
            int x,y;
            cin>>x>>y;
            if(y>100000)continue;
            for(j=1;j<=y;j++)//把多个分解成每一个,01背包,取或不取
            {
                w[k]=x,v[k++]=1;//漂亮值看作重量(因为容量是luck,要恰好装满),每个的价值都是1,因为最后要求最小的组成个数(理解为背包中的最小价值)
            }
        }
        for(i=1;i<=k-1;i++)//01背包模板
        {
            for(j=m;j>=1;j--)
            {
                if(j<w[i])dp[j]=dp[j];
                else dp[j]=min(dp[j-w[i]]+v[i],dp[j]);
            }
        }
        cout<<dp[m]<<endl;//最小价值(最少的个数
    } 
    return 0;
}
原文地址:https://www.cnblogs.com/ydw--/p/10987163.html