01背包问题(动态规划DP)

原题

01背包问题

有n个重量和价值分别为wi,vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
1<=n<=100 
1<=wi,vi<=100
1<=W<=10000

样例输入


n=4
(w,v)={(2,3),(1,2),(3,4),(2,2)}
W=5

样例输出


7(选择0、1、3号物品)

代码

递归写法(记忆化搜索)
int n,W;
int w[MAX_N],v[MAX_N]
//记忆化数组
int dp[MAX_N+1][MAX_N+1];
//从第i个物品开始挑选总重小于j的部分
int rec(int i,int j)
{
    if(dp[i][j]>=0)
    {
        return dp[i][j];
    }
    int res;
    if(i==n)
    {
        //没有剩余物品
        res=0;
    }
    else if(j

递推写法(逆向进行)
dp[i][j]定义为从第i个物品开始挑选总重小于j的部分
dp[n][j]=0
dp[i][j]= dp[i+1][j] (j
dp[i][j]= max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]) (j>=w[i])

int n,W;
int w[MAX_N],v[MAX_N]
//DP数组
int dp[MAX_N+1][MAX_N+1];
void solve()
{
    for(int j=0;j<=W;j++)
    {
        dp[n][j]=0;
    }
    for(int i=n-1;i>=0;i--)
    {
        for(int j=0;j<=W;j++)
        {
            if(j
递推写法(正向进行)
dp[i+1][j]定义为从前i个物品中选出总重量不超过j的物品时总价值的最大值
dp[0][j]=0
dp[i+1][j]=dp[i][j]  (j
dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]) (j>=w[i])
int n,W;
int w[MAX_N],v[MAX_N]
//DP数组
int dp[MAX_N+1][MAX_N+1];
void solve()
{
    for(int j=0;j<=W;j++)
    {
        dp[0][j]=0;
    }
    for(int i=0;i
状态转移
从“前i个物品中选取总重不超过j时的状态”向“前i+1个物品中选取总重不超过j”和“前i+1个物品中选取总重不超过j+w[i]时的状态”的转移。
int n,W;
int w[MAX_N],v[MAX_N]
//DP数组
int dp[MAX_N+1][MAX_N+1];
void solve()
{
    memset(dp,0,sizeof(dp));
    for(int i=0;i
注:文章内容源于《挑战程序设计竞赛》(第二版)



你可能感兴趣的:(动态规划(DP),动态规划DP,挑战程序设计竞赛第二版,背包问题)