poj1170

来源:互联网 发布:漫画配音软件 编辑:程序博客网 时间:2024/05/22 06:19

poj1170
题意:给很多件商品,给出组合购买和单独购买的价格,要求求出购买指定种类指定数量的各类商品的最小花费。
思路:典型的背包问题,可以使用记忆化搜索的思路来写,比用for循环写简单得多。注意,方案不存在的话,返回 花费为无穷大。

#include<cstdio>#include<iostream>#include<cstring>#include<map>#include<set>#include<algorithm>#include<sstream>#include<string>using namespace std;int b;int trans[1000];struct NEED{    int k,p;}need[10];int dp[10][10][10][10][10];int s;struct product{    int num[10];    product(){memset(num,0,sizeof num);}    int p;}pro[110];int dfs(int n0,int n1,int n2,int n3,int n4){    if(n0<0||n1<0||n2<0||n3<0||n4<0)        return 0x3f3f3f3f;    if(dp[n0][n1][n2][n3][n4]!=-1)        return dp[n0][n1][n2][n3][n4];    int ans=0;    ans=dp[n0][n1][n2][n3][n4]=n0*need[0].p+n1*need[1].p+n2*need[2].p+n3*need[3].p+n4*need[4].p;    for(int i=0;i<s;i++)    {        ans=min(ans,pro[i].p+dfs(n0-pro[i].num[0],n1-pro[i].num[1],n2-pro[i].num[2],n3-pro[i].num[3],n4-pro[i].num[4]));    }    return dp[n0][n1][n2][n3][n4]=ans;}int main(){    while(scanf("%d",&b)!=EOF)    {        memset(need,0,sizeof need);        memset(dp,-1,sizeof dp);        for(int i=0;i<b;i++)        {            int c,k,p;            scanf("%d%d%d",&c,&k,&p);            trans[c]=i;            need[i].k=k;            need[i].p=p;        }        scanf("%d",&s);        memset(pro,0,sizeof pro);        for(int i=0;i<s;i++)        {            int n;            scanf("%d",&n);            for(int j=0;j<n;j++)            {                int k,c;                scanf("%d%d",&c,&k);                pro[i].num[trans[c] ]=k;            }            int p;            scanf("%d",&p);            pro[i].p=p;        }        dp[0][0][0][0][0]=0;        printf("%d\n",dfs(need[0].k,need[1].k,need[2].k,need[3].k,need[4].k));    }    return 0;}
0 0
原创粉丝点击