zoukankan      html  css  js  c++  java
  • 01背包【模板】

    01背包是最基础的背包问题,特点是:每种物品仅有一件,能够选择放或不放。

    用子问题定义状态:即F[i,v] 表示前i 件物品恰放入一个容量为v 的背包能够获得的最大价值。则其状态转移方程便是:
    F[i,v]=max(F[i,v],F[i-1,v-w[i]]+v[i])
    这个方程很重要,基本上全部跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详解一下:“将前i 件物品放入容量为v 的背包中”这个子问题,若仅仅考虑第i 件物品的策略(放或不放)。那么就能够转化为一个仅仅和前 i - 1 件物品相关的问题。假设不放第i 件物品,那么问题就转化为“前i - 1 件物品放入容量为v 的背包中”,价值为F[i - 1; v];假设放第i 件物品,那么问题就转化为“前i - 1 件物品放入剩下的容量为v - Ci 的背包中”,此时能获得的最大价值就是F[i - 1; v - Ci] 再加上通过放入第i 件物品获得的价值Wi。伪代码例如以下:
    F[0,0..V ]<--0
    for i<--1 to N
        for v<--Ci to V

             F[i; v]<--max{F[i - 1, v], F[i - 1, v - Ci] +Wi}

    代码例如以下:

    # include <stdio.h>  
    # include <stdlib.h>  
    # include <string.h>  
    # define max(x,y) x>y?

    x:y; int v[1001];//价值 int w[1001];//重量 int dp[1001][1001]; int main() { int n,m,i,j; while(scanf("%d%d",&m,&n)!=EOF) { memset(dp,0,sizeof(dp));//初始化 for(i=1; i<=n; i++) scanf("%d%d",&w[i],&v[i]); for(i=1; i<=n; i++) // 物品数 for(j=m; j>=w[i]; j--) //放入背包 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);// 与前面对照 printf("%d ",dp[n][m]); } return 0; }



  • 相关阅读:
    [C/C++] 指针数组和数组指针
    [计算机网络] DNS劫持和DNS污染
    [计算机网络-数据链路层] CSMA、CSMA/CA、CSMA/CD详解
    [BinaryTree] 二叉树常考知识点
    NODE-windows 下安装nodejs及其配置环境
    MATLAB/Excel-如何将Excel数据导入MATLAB中
    Excel-怎样实现行列转置
    一篇文章学懂Shell脚本
    SQL-MySQL使用教程-对MySQL的初步尝试
    资源贴-在线编译环境推荐
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6912237.html
Copyright © 2011-2022 走看看