寒假数据结构学习Day10

本文介绍了动态规划在解决01背包问题中的应用,通过定义dp数组、确定递推公式和初始化过程,演示了如何使用C语言实现01背包算法,并随后扩展到整数拆分问题,优化乘积的最大化。
摘要由CSDN通过智能技术生成

动态规划学习(记住动规五部曲)

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

做题的时候一定要遵从这五步来进行,今天学的是

01背包问题

基本题型:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define bag_weight 4
#define MAX(a,b)((a>b)?(a):(b))

//dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
void backPack(int* weight, int weightSize, int* costs, int costSize, int bagWeight) {
    int** dp = (int**)malloc(weightSize * sizeof(int*));
    //for (int i = 0; i < bagWeight; i++)
    //    dp[i] = (int*)malloc((bagWeight + 1) * sizeof(int));
    memset函数用来赋值
    //memset(dp, 0, sizeof(int) * weightSize * (bagWeight + 1));

    dp = (int**)malloc(weightSize * sizeof(int*));
    for (int i = 0; i < weightSize; i++)
        dp[i] = (int*)malloc((bagWeight + 1) * sizeof(int));
    memset(dp, 0, sizeof(int) * weightSize * (bagWeight + 1));

    // 当背包容量大于物品0的重量时,将物品0放入到背包中-->也就是把第一行都赋值成物品0的价值
    int i, j;
    for (j = weight[0]; j <= bagWeight; j++)
        dp[0][j] = costs[0];
    //先遍历物品,再遍历重量
    for (i = 1; i < weightSize; i++)
        for (j = 0; j <= bagWeight; j++)
        {
            if (j < weight[i])
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = MAX(dp[i - 1][j], dp[i - 1][j - weight[i]] + costs[i]);
        }
    printf("%d\n", dp[weightSize - 1][bagWeight]);
    return;
}

int main() {
    int weight[3] = { 1,3,4 };
    int costs[3] = { 15,20,30 };
    backPack(weight, sizeof(weight) / sizeof(weight[0]), costs, sizeof(costs) / sizeof(costs[0]), bag_weight);

    return 0;
}

新学函数:memst

        给数组赋值

还有c语言中可以直接用int*来表示一维数组

int**表示二维数组。

敲了个整数拆分问题

题意:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

#include<stdio.h>
#include<stdlib.h>
int* initDP(int num) {
    int* dp = (int*)malloc(sizeof(int) * (num + 1));
    int i;
    for (i = 0; i < num + 1; i++) {
        dp[i] = 0;
    }
    return dp;
}
int max(int num1,int num2,int num3) {
    int tempMax = num1 > num2 ? num1 : num2;
    return tempMax > num3 ? tempMax : num3;
}

int integerBreak(int n) {
    int* dp = initDP(n);
    dp[2] = 1;
    int i;
    for (i = 3; i <= n; i++) {
        int j;
        for (j = 1; j < i - 1; j++) {
            dp[i] = max(dp[i], j * (i - j), j * dp[i - j]);
        }
    }
    return dp[n];
}

int main() {
    int n;
    while (scanf("%d", &n) == 1) {
        printf("%d", integerBreak(n));
    }
    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值