01背包一维和二维数组解法,01背包9题详细讲述附带教学视频)高数Umaru系列(9)——哈士奇

01背包问题,是用来介绍动态规划算法最经典的例子
01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }
f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。
Pi表示第i件物品的价值。
决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ?
问题不再描述,这里直接放如何去解决。
01背包一维和二维数组解法,01背包9题详细讲述附带教学视频)高数Umaru系列(9)——哈士奇_第1张图片
01背包一维和二维数组解法,01背包9题详细讲述附带教学视频)高数Umaru系列(9)——哈士奇_第2张图片
01背包一维和二维数组解法,01背包9题详细讲述附带教学视频)高数Umaru系列(9)——哈士奇_第3张图片
01背包一维和二维数组解法,01背包9题详细讲述附带教学视频)高数Umaru系列(9)——哈士奇_第4张图片
视频详细解说,适合一点看不懂公式和图的人,讲得很好
https://www.bilibili.com/video/av36136952?from=search&seid=14797432733978841510
下面的题类似
高数Umaru系列(9)——哈士奇
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
由于高数巨养的喵星人太傲娇了,要天天吃新鲜猫粮而且还经常欺负高数巨,所以高数巨决定买几条哈士奇尝尝鲜。这天高数巨来到了二手狗市场买哈士奇,高数巨看完了所有的哈士奇,记下了每条哈士奇的价格,并根据对它们的好感程度给它们每只都赋予了一个萌值。高数现在手里有X元,她想通过购买若干条哈士奇来获得尽可能多的萌值。现在给定高数巨手里的钱X以及N条哈士奇的价格和萌值,求高数巨最多可获得多少萌值

Input
多组输入。

对于每组输入,第一行有两个整数N,X(1 < = N < = 100,1 < = X < = 1000),分别表示哈士奇的数量和高数巨的钱数

接下来的N行每行有两个整数Pi,Mi(1 < = Pi,Mi < = 100),分别表示第i条哈士奇的价格和萌值

Output
对于每组数据,输出一个整数,表示高数巨最多可以获得的萌值,每组输出占一行

Sample Input
2 100
50 20
60 40
3 100
20 55
20 35
90 95
1 10
20 50
Sample Output
40
95
0

#include

using namespace std;
int f[1001][1001];
int main()
{
    int m, p;///m为萌值,p为价格
    int n, x;///n为数量,x为金钱
    while(cin>>n>>x)
    {
        memset(f, 0, sizeof(f));///初始化数组
        for(int i = 1; i <= n; i++)///数量从1开始
        {
            cin>>p>>m;
            for(int j = 1; j <= x; j++)
            {
                if(j < p)///第i个太贵,钱不够
                    f[i][j] = f[i - 1][j];
                ///第i个买和不买看哪一个萌值大,j - p是少的钱,+ m是增加的萌值
                else
                    f[i][j] = max(f[i - 1][j], f[i - 1][j - p] + m);
            }
        }
        cout<<f[n][x]<<endl;
    }
    return 0;
}

下面是刚学的,将二维数组一维化
01背包九讲

#include

using namespace std;

int n, m;
int f[1010];
int v[1100], w[1010];
int main()
{
    while(cin>>n>>m)
    {
        memset(f, 0, sizeof(f));
        memset(v, 0, sizeof(v));
        memset(w, 0, sizeof(w));
        for(int i = 1; i <= n; i++)
            cin>>v[i]>>w[i];
        for(int i = 1; i <= n; i++)
            for(int j = m; j >= v[i]; j--)///这里j = m为初始钱,只要j >=v[i],说明这件东西满足购买条件
            {
                ///cout<方便理解过程测试用
                f[j] = max(f[j], f[j - v[i]] + w[i]);
                ///cout<<"输出最大f[j]"<方便理解过程测试用
            }
        cout<<f[m]<<endl;
    }
    return 0;
}

你可能感兴趣的:(算法设计-动态规划)