动态规划-背包问题

  • 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]的值即可。

 

posted @ 2018-02-05 21:16  TQCAI  阅读(202)  评论(0编辑  收藏  举报