HDOJ  1114   Piggy-Bank

来源:互联网 发布:ubuntu安装qq拼音 编辑:程序博客网 时间:2024/06/04 23:20

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1114

 

以下有三种做法,自己在网上找的。

自己开始学习背包问题,感觉这几种做的方法都好,

 

题解:想求重量为W(k)时的最小价值V(k),给定的重量选择为weight[],对应的价值分别为value[];

则若知道W(k)的前一步W(k-1)时所对应的价值,

由于W(k-1)+weight[i] = W(k),只要遍历value[]数组,得

出V(k)的最小值即可,,,,,,,,,,,,,,,,
dp[k] = 0…………k = 0;
dp[k] = min(value[j] + dp[k - weight[j]])…………k >=weight[j];
其中,1=< j <= n,若dp[k - weight[j]]) =-1,表示它是无穷大,重量不能达到

#include <stdio.h>
#include <string.h>
struct coin
{
    int v;
    int w;
};
coin cc[501];
int dp[10001];
int main()
{
    int t, e, f,total, n, min;
    int i, j,k;
    scanf("%d",&t);
    while(t--)
    {
       scanf("%d%d", &e, &f);
       total = f - e;
       scanf("%d", &n);
       min = 10001;
       for (i = 0; i < n; i++)
       {
           scanf("%d%d", &cc[i].v,&cc[i].w);
           if (min > cc[i].w)
               min = cc[i].w;
       }
       memset(dp, -1, sizeof(dp));
       dp[0] = 0;
       for (k = min; k <= total; k++)
       {
           for (j = 0; j < n; j++)
           {
               i = k - cc[j].w;
               if (i < 0 || dp[i] == -1)
                   continue;
               if (dp[i] + cc[j].v < dp[k] || dp[k] == -1)
               {
                   dp[k] = dp[i] + cc[j].v;
               }
           }
       }
       if (dp[total] == -1)
           printf("This is impossible.\n");
       else
           printf("The minimum amount of money in the piggy-bank is%d.\n",dp[total]);;
    }

    return0;
}

***************************************************
若dp[i](重量为i时的最小值)是已知的,此时让重量在i基础上向前滚动,weight[j](1=<j<=n)的距离,

同时让dp[i+weight[j]]与dp[i]+value[j]作比较,

使得dp[i+weight[j]]={dp[i+weight[j]], dp[i]+value[j]}.

这样得到的dp[k](令i+weight[j]=k)不一定是最小的,可能以后的滚动还要修改它,

只有dp[i]是确定的,以后无论怎么滚动都不会再滚到它了。

直至滚到total值时,全部比较完后停止

#include <iostream>
#include <algorithm>
using namespace std;

struct coin
{
    int v;
    int w;
};
coin cc[501];
int dp[10001];
bool comp(coin a, coin b)
{
    if(a.w< b.w)
       return true;
    returnfalse;
}
int main()
{
    int t, e, f,total, n;
    int i, j,k;
    scanf("%d",&t);
    while(t--)
    {
       scanf("%d%d", &e, &f);
       total = f - e;
       scanf("%d", &n);
       for (i = 0; i < n; i++)
       {
           scanf("%d%d", &cc[i].v,&cc[i].w);
       }
       sort(cc, cc + n, comp);
       memset(dp, -1, sizeof(dp));
       dp[0] = 0;
       for (i = 0; i <= total; i++)
       {
           if (dp[i] == -1)
               continue;
           for (j = 0; j < n; j++)
           {
               k = i + cc[j].w;
               if (k > total)
                if(dp[i] + cc[j].v < dp[k] || dp[k] == -1)
               {
                   dp[k] = dp[i] + cc[j].v;
               }
           }
       }
       if (dp[total] == -1)
           cout << "This isimpossible.\n";
       else
           cout << "The minimum amount of moneyin the piggy-bank is " << dp[total]<< ".\n";
    }
   
    return0;
}
********************************************
#include <stdio.h>
int main()
{
    intt,e,f,n,p[510],w[510],v[10010],l,i,j,ans;
   scanf("%d",&t);
   while(t--)
    {
       scanf("%d%d",&e,&f);
       l=f-e;
       for(i=1;i<=l;i++)
           v[i]=99999999;
       v[0]=0;
       scanf("%d",&n);
       for(i=1;i<=n;i++)
           scanf("%d%d",&p[i],&w[i]);
       for(i=1;i<=n;i++)
       {
           for(j=w[i];j<=l;j++)
           {
               if(v[j-w[i]]<99999999)
               {
                   if(v[j-w[i]]+p[i]<v[j])
                       v[j]=v[j-w[i]]+p[i];
               }
           }
       }
       if(v[l]<99999999)
           printf("The minimum amount of money in the piggy-bank is%d.\n",v[l]);
       else
           printf("This is impossible.\n");
    }
    return0;
}

0 0