2015年一月21日,背包问题

来源:互联网 发布:免费的相亲软件 编辑:程序博客网 时间:2024/06/07 19:57

*1*,简单背包问题,背包能否被正好完全填满

# include<stdio.h># include<string.h>int date[1005];int f(int w,int s){    if(w==0)return 1;//正好    if(w<0||w>0 &&s==0) return 0;    if(f(w-date[s],s-1)) return 1;//退出来再选下一个     return f(w,s-1);//选择下一个}int main(){ int i,Weight,n; while(scanf("%d %d",&Weight,&n)!=EOF) {     memset(date,0,sizeof(date)); for(i=1;i<=n;i++)  scanf("%d",&date[i]);    if(f(Weight,n))       printf("YES\n"); else  printf("NO\n"); } return 0;}





*2*01背包问题,二维数组

#include<stdio.h>  #include<string.h>#define  max(x,y) (x)>(y)?(x):(y)  int f[1111][1111];  //全局变量,自动初始化为0  int weight[1111];  int value[1111];  int main()  {    int N,M;      while(~scanf("%d%d",&N,&M))      //物品个数    //背包容量      {    memset(f,0,sizeof(f));    for (int i=1;i<=N; i++)      {          scanf("%d",&weight[i]);          //物品个数     scanf("%d",&value[i]);        }      for (int i=1; i<=N; i++)             for (int j=1; j<=M; j++)          {               if (weight[i]<=j)             {                  f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);              }            else                  f[i][j]=f[i-1][j];          }            printf("%d\n",f[N][M]);//输出最优解          }return 0;}




*3*01背包问题,一维数组


# include<stdio.h># include<string.h>int f[2000],V;void ZeroOnePack(int cost,int weight)////***01背包模板,一维数组***///{      int v;      for(v=V;v>=cost;v--)           if(f[v]<f[v-cost]+weight)                 f[v]=f[v-cost]+weight;}int main(){      int i,t,n,c[1001],w[1001];               scanf("%d%d",&n,&V);           for(i=0;i<n;i++){scanf("%d",&w[i]);                 scanf("%d",&c[i]);}           memset(f,0,sizeof(f));           for(i=0;i<n;i++)                 ZeroOnePack(c[i],w[i]);           printf("%d\n",f[V]);          return 0;}


例题

  小P寻宝记——粗心的基友

Time Limit: 1000MS Memory limit: 65536K

题目描述

这对好基友他们在经历无数的艰难险阻后,终于找到了宝藏。无奈的是这一对好基友竟然是一样的粗心,又忘记了带一个大一点的包包,可惜啊、、选择又出现了啊、、
已知包的体积是v,每种宝贝只有一种,宝贝的体积是pi,价值是wi。求出这对粗心的基友可以最多带走价值多少的宝藏。

输入

输入数据有多组。
每组第一行有两个正整数n(n <= 10000)和v(v <= 10000)分别表示n种宝贝和包的体积。
接下来n行,每行有两个正整数vi, wi。
分别表示每种宝藏的体积vi (vi<=1000),价值wi(wi<=1000)。

输出

这对基友所能带走的最多的宝藏。

示例输入

5 10 1 52 43 34 25 1

示例输出

14

#include <stdio.h>  #define MAXN 10111  //**AC**//int max_num(int a, int b){      return a > b? a : b;  }int dp[MAXN], w[MAXN], p[MAXN];  int main(){        int n, v, i, j;          while(scanf("%d%d",&n,&v)!=EOF)  //物品种类和背包容积         {        for(i=1; i<=n; i++)              {           scanf("%d%d",&w[i],&p[i]);  //宝贝的体积是w,价值是p             }        for(i=0;i<=v;i++){            dp[i] = 0;        }        for(i=1; i<=n; i++){            for(j=v;j>=0; j--){                if(j>=w[i]) dp[j] = max_num(dp[j],dp[j-w[i]]+p[i]);              }        }        printf("%d\n", dp[v]);          }      return 0;}




0 0
原创粉丝点击