zoukankan      html  css  js  c++  java
  • 动态规划-背包问题

    • 1.P1060 开心的金明

    https://www.luogu.org/problemnew/solution/P1164

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100
    #define MAX 1<<30
    #define V vector<int>
    
    using namespace std;
    
    int v[LEN],p[LEN];//价钱,重要度
    int dp[LEN][30001];
    int n,m;
    
    int main(){
    //    freopen("D:/CbWorkspace/动态规划/开心的王明.txt","r",stdin);
        int i,j;
        scanf("%d %d",&n,&m);
        F(i,1,m+1){
            scanf("%d",&v[i]);
            scanf("%d",&p[i]);
        } 
        F(i,1,m+1){
            F(j,1,n+1){
                if(v[i]>j)
                    dp[i][j]=dp[i-1][j];
                else{
                    dp[i][j]=max(dp[i-1][j],
                                dp[i-1][j-v[i]]  +  p[i] * v[i]);
                }
            }
        }
        printf("%d",dp[m][n]);
        return 0;
    }
    View Code

    • 2.P1164 小A点菜

    https://www.luogu.org/problemnew/show/P1164

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100
    #define MAX 1<<30
    #define V vector<int>
    
    using namespace std;
    
    int v[LEN];//价钱
    int dp[101][1001];
    int n,m;
    
    int main(){
        freopen("小A点菜.txt","r",stdin);
        int i,j;
        scanf("%d %d",&n,&m);//n种,m元
        F(i,1,n+1) scanf("%d",&v[i]);
        F(i,1,n+1){
            bool isSet=false;
            F(j,1,m+1){
                if(isSet){ dp[i][j]=dp[i][j-1];continue;}
                if(v[i]>j)
                    dp[i][j]=dp[i-1][j];
                else{
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+1);
                }
            }
        }
        printf("%d",dp[n][m]);
        return 0;
    }
    View Code

    定义f[i][j]为用前i道菜用光j元钱的办法总数,其状态转移方程如下:

    1if(j==第i道菜的价格)f[i][j]=f[i-1][j]+1;
    
    (2if(j>第i道菜的价格) f[i][j]=f[i-1][j]+f[i-1][j-第i道菜的价格];
    
    (3if(j<第i道菜的价格) f[i][j]=f[i-1][j];

    说的简单一些,这三个方程,每一个都是在吃与不吃之间抉择。若钱充足,办法总数就等于吃这道菜的办法数与不吃这道菜的办法数之和;若不充足,办法总数就只能承袭吃前i-1道菜的办法总数。依次递推,在最后,我们只要输出f[n][m]的值即可。

  • 相关阅读:
    Java学习之路(一)——JDK的下载与安装
    无法将“add-migration”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。解决方案
    VS2019只能提示选中首选项的快捷键切换
    Visual Studio空格变成点的快捷键切换
    Visual Studio 2019 打开即时窗口
    完全卸载node.js
    安装node.js和vue
    在后台启动Redis
    mysql的数据库优化方案
    hadoop
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8419468.html
Copyright © 2011-2022 走看看