带走更多的糖果

桌子上有N包糖果,第[i]包糖果有w[i]颗糖,但每包糖不能拆开。小明的妈妈只允许小明拿走不超过C颗糖。小明想尽可能的拿走更多的糖。请问小明可以拿走最大的糖果数目。

输入 第一行 N C N为总共的包数,,C为最多可拿走的数目。
第二行 N个数,代表每一包的数目
输出 拿走的最大数目。

例如
输入
4 10
7 7 5 4

输出 9

此题属于01背包问题,但与普通的01背包 有写差别。
经典的背包问题,一般有两个参量,如价值和重量。要求不超过重量能达到的价值最大。

而本题只给出了数量这一个参量。其实完全可以看作,其价值等于重量,或者价值与重量成正比。这样又回到了经典01背包的解决思路。

首先使用搜索的方法

#include
using namespace std;
int num[20];
int n;
int c;
int fun(int sum,int k)
{
    if (sum>tc)
    {
        return 0;
    }
    if (k>=n)
    {
        return sum;
    }
    return max(fun(sum+num[k],k+1),fun(sum,k+1));
}
int main()
{
    cin>>n>>c;
    for (int i=0;icin>>num[i];
    }
   cout<< fun(0,0);
}

动态规划

#include
using namespace std;

int n,t;
int  num[20];
int maxnum[40][400];
int main()
{
    cin>>n>>t;
    for (int i=0;icin>>num[i];
    }

    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=t;j++)
        {
            if (j1][j];
            else
                maxnum[i][j]=max(maxnum[i-1][j-num[i]]+num[i],maxnum[i-1][j]);
        }
    }
    cout<

降维之后

int n,t;
int  num[20];
int maxnum[400];
int main()
{
    cin>>n>>t;
    for (int i=0;icin>>num[i];
    }

    for (int i=1;i<=n;i++)
    {
        for (int j=t;j>=num[i];j--)
        {
                maxnum[j]=max(maxnum[j-num[i]]+num[i],maxnum[j]);
        }
    }
    cout<

你可能感兴趣的:(动态规划,递归回溯)