现在的位置: 首页 > 综合 > 正文

dp专辑 J – Shopping Offers [背包]

2013年03月28日 ⁄ 综合 ⁄ 共 3342字 ⁄ 字号 评论关闭

被坑爹了好几个小时大哭郁闷呀~~~ 

题意:

给出若干个商品的单价,再给出若干套商品的优惠组合,最后指定要买K种商品,分别买Ki个,求花费最小。

分析:

由于最多只有五种商品,每种商品最多五个,直接开一个五维数组,dp[N][N][N][N][N],每一维表示该商品的个数,dp[v1][v2][v3][v4][v5]表示第一种商品v1个,.....,第五种商品v5个的最小花费,用完全背包的方法解决~敲打 
  

注意:为了统一处理,把单价商品作优惠商品处理,具体看代码~

//WA CODE:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;

const int N = 10;
const int INF = 999999999;

int dp[N][N][N][N][N];
int num[N];
int price[N];
int map[1005];// code -- P[map[code]]
struct special
{
    int num[5];
    int price;
} S[200];
inline void init(int i)
{
    for(int j=0; j<5; j++)
        S[i].num[j]=0;
    S[i].price=0;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int b,s,t,m;
    int v1,v2,v3,v4,v5;
    int code,n;
    while(scanf("%d",&b)!=EOF)
    {
        if(b==0)
            break;
        memset(num,0,sizeof(num));
        memset(price,0,sizeof(price));
        m=0;
        for(int i=0; i<b; i++)
        {
            scanf("%d %d %d",&code,&num[i],&price[i]);
            map[code]=i;
            //单价物品作为优惠商品处理
            init(m);
            S[m].num[i]=1;
            S[m].price=price[i];
            m++;
        }
        scanf("%d",&s);
        for(int i=0; i<s; i++)
        {
            scanf("%d",&t);
            init(m);
            for(int j=0; j<t; j++)
            {
                scanf("%d %d",&code,&n);
                int t=map[code];
                S[m].num[t]=n;
            }
            scanf("%d",&S[m].price);
            m++;
        }
        for(v1=0; v1<N; ++v1)
            for(v2=0; v2<N; ++v2)
                for(v3=0; v3<N; ++v3)
                    for(v4=0; v4<N; ++v4)
                        for(v5=0; v5<N; ++v5)
                            dp[v1][v2][v3][v4][v5]=INF;
        dp[0][0][0][0][0] = 0 ;
        for(int i=0; i<m; ++i)
            for(v1=S[i].num[0]; v1<=num[0]; ++v1)
                for(v2=S[i].num[1]; v2<=num[1]; ++v2)
                    for(v3=S[i].num[2]; v3<=num[2]; ++v3)
                        for(v4=S[i].num[3]; v4<=num[3]; ++v4)
                            for(v5=S[i].num[4]; v5<=num[4]; ++v5)
                                if(dp[v1][v2][v3][v4][v5] > dp[v1-S[i].num[0]][v2-S[i].num[1]][v3-S[i].num[2]][v4-S[i].num[3]][v5-S[i].num[4]] + S[i].price )
                                    dp[v1][v2][v3][v4][v5] = dp[v1-S[i].num[0]][v2-S[i].num[1]][v3-S[i].num[2]][v4-S[i].num[3]][v5-S[i].num[4]] + S[i].price;
        printf("%d\n",dp[num[0]][num[1]][num[2]][num[3]][num[4]]);
    }
    return 0;
}

我把主函数里的while()去掉了就AC了,你说多疼呀大哭大哭大哭大哭

坑爹的哭哭哭哭

int main()
{
    //freopen("in.txt","r",stdin);
    int b,s,t,m;
    int v1,v2,v3,v4,v5;
    int code,n;
    while(scanf("%d",&b)!=EOF)
    {
        ... ...
    }
    return 0;
}

//AC CODE:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;

const int N = 10;
const int INF = 999999999;

int dp[N][N][N][N][N];
int num[N];
int price[N];
int map[1005];// code -- P[map[code]]
struct special
{
    int num[5];
    int price;
} S[200];
inline void init(int i)
{
    for(int j=0; j<5; j++)
        S[i].num[j]=0;
    S[i].price=0;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int b,s,t,m;
    int v1,v2,v3,v4,v5;
    int code,n;
    scanf("%d",&b);
    memset(num,0,sizeof(num));
    memset(price,0,sizeof(price));
    m=0;
    for(int i=0; i<b; i++)
    {
        scanf("%d %d %d",&code,&num[i],&price[i]);
        map[code]=i;
        //单价物品作为优惠商品处理
        init(m);
        S[m].num[i]=1;
        S[m].price=price[i];
        m++;
    }
    scanf("%d",&s);
    for(int i=0; i<s; i++)
    {
        scanf("%d",&t);
        init(m);
        for(int j=0; j<t; j++)
        {
            scanf("%d %d",&code,&n);
            int t=map[code];
            S[m].num[t]=n;
        }
        scanf("%d",&S[m].price);
        m++;
    }
    for(v1=0; v1<N; ++v1)
        for(v2=0; v2<N; ++v2)
            for(v3=0; v3<N; ++v3)
                for(v4=0; v4<N; ++v4)
                    for(v5=0; v5<N; ++v5)
                        dp[v1][v2][v3][v4][v5]=INF;
    dp[0][0][0][0][0] = 0 ;
    for(int i=0; i<m; ++i)
        for(v1=S[i].num[0]; v1<=num[0]; ++v1)
            for(v2=S[i].num[1]; v2<=num[1]; ++v2)
                for(v3=S[i].num[2]; v3<=num[2]; ++v3)
                    for(v4=S[i].num[3]; v4<=num[3]; ++v4)
                        for(v5=S[i].num[4]; v5<=num[4]; ++v5)
                            if(dp[v1][v2][v3][v4][v5] > dp[v1-S[i].num[0]][v2-S[i].num[1]][v3-S[i].num[2]][v4-S[i].num[3]][v5-S[i].num[4]] + S[i].price )
                                dp[v1][v2][v3][v4][v5] = dp[v1-S[i].num[0]][v2-S[i].num[1]][v3-S[i].num[2]][v4-S[i].num[3]][v5-S[i].num[4]] + S[i].price;
    printf("%d\n",dp[num[0]][num[1]][num[2]][num[3]][num[4]]);
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.