• 背包问题


    这里写图片描述

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    #define MAX_N 100
    #define MAX_W 1000
    
    int n,W;
    
    // 从第i个物品开始挑选总重量小于j的部分
    int rec(int i,int j)
    {
        int res;
        if(i==n)
            res=0;  // 已经没有剩余物品了
        else if(j<w[i])
            res=rec(i+1,j);    // 无法挑选该物品
        else
            res=max(rec(i+1,j),rec(i+1,j-w[i])+v[i]);  // 挑选与不挑选的情况中选择最大的一种
        return res;
    }
    
    void solve()
    {
        printf("%d
    ",rec(0,W));
    }
    
    int main()
    {
        printf("n W:
    ");
        scanf("%d %d",&n,&W);
    
        for(int i=0;i<n;i++)
        {
            printf("w[%d] v[%d]:
    ",i,i);
            scanf("%d %d",&w[i],&v[i]);
        }
    
        solve();
        return 0;
    }

    优化——记忆化搜索

    #include <cstdio>
    #include <iostream>
    #include <memory.h>
    
    using namespace std;
    
    #define MAX_N 100
    #define MAX_W 1000
    
    int n,W;
    int w[MAX_N],v[MAX_N];
    
    int dp[MAX_N+1][MAX_W+1];
    
    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<w[i])
            res=rec(i+1,j);
        else
            res=max(rec(i+1,j),rec(i+1,j-w[i])+v[i]);
        return dp[i][j]=res;
    }
    
    void solve()
    {
        memset(dp,-1,sizeof(dp));
        printf("%d
    ",rec(0,W));
    }
    
    int main()
    {
        printf("n W:
    ");
        scanf("%d %d",&n,&W);
    
        for(int i=0;i<n;i++)
        {
            printf("w[%d] v[%d]:
    ",i,i);
            scanf("%d %d",&w[i],&v[i]);
        }
    
        solve();
        return 0;
    }
    

    二重循环

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    #define MAX_N 100
    #define MAX_W 1000
    
    int n,W;
    int w[MAX_N],v[MAX_N];
    
    int dp[MAX_N+1][MAX_W+1];
    
    void solve()
    {
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<=W;j++)
            {
                if(j<w[i])
                    dp[i][j]=dp[i+1][j];
                else
                    dp[i][j]=max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]);
            }
        }
        printf("%d
    ",dp[0][W]);
    }
    
    int main()
    {
        printf("n W:
    ");
        scanf("%d %d",&n,&W);
    
        for(int i=0;i<n;i++)
        {
            printf("w[%d] v[%d]:
    ",i,i);
            scanf("%d %d",&w[i],&v[i]);
        }
    
        solve();
        return 0;
    }

    i的循环为正向进行情况:

    void solve()
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<=W;j++)
            {
                if(j<w[i])
                {
                    dp[i+1][j]=dp[i][j];
                }
                else
                {
                    dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]);
                }
            }
        }
        printf("%d
    ",dp[n][W]);
    }
    
  • 相关阅读:
    JAVA 读取Properties文件内容乱码 解决方法
    java代码求IP和mac地址
    jsp 清除session的方法
    Go语言字符串和正则表达式
    go语言:字符串操作
    博客园美化基本完成!!!
    美化了一下页面
    第一天:初入博客园
    c语言实参与形参的区别
    c链表中指针的一些用法要点
  • 原文地址:https://www.cnblogs.com/NoMasp/p/4540443.html
Copyright © 2020-2023  润新知