usaco shopping offers 解析 and C 语言实现

来源:互联网 发布:入骨相思知不知txt番外 编辑:程序博客网 时间:2024/05/29 15:23

题意:现在商场正在打折,打折的方式是同时买规定的的物品会比分开买便宜,现在告诉你打折的方式和要买的物品,求最少的钱,有个条件是不可以多买物品。



本题是典型的动态规划,对于动态规划问题,关键是找出其最优子结构,然后写出其递归式,然后,填表及可,另外注意各种边界条件。


对于本题,递归式可写为:

 d[a1][a2][a3][a4][a5]=min(d[a1][a2][a3][a4][a5],d[a1-b1][ a2-b2][ a3-b3][ a4-b4][ a5-b5] + reduce[i] )


d[a1][a2][a3][a4][a5] 表示第 1 个物品买 a1 个,第 2 个物品买 a2 个,第 3 个物品买 a3 个,第 4 个物品买 a4 个,第 5 个物品买 a5 个的最小值。;b1、b2、b3、b4、b5 表示打折要买的物品数目。


/*ID: abc18711LANG: CTASK: shopping*/#include <stdio.h>#include <string.h>struct good{int c;int k;int r;};struct good a[6];int offer[100][1000];int reduce[100];int d[6][6][6][6][6];int num[100];int min(int a,int b){if(a < b)return a;elsereturn b;}int main(){    FILE *fin = fopen("shopping.in", "r");FILE *fout = fopen("shopping.out", "w");        int s,n,i,j,a1,a2,a3,a4,a5,b1,b2,b3,b4,b5;        fscanf(fin, "%d", &s);            memset(offer, 0, sizeof(offer));        for(i=0;i<6;i++) a[i].c=a[i].k=0;        for(i=1; i<=s; i++)        {            fscanf(fin, "%d", &num[i]);            for(j=1; j<=num[i]; j++)            {                fscanf(fin, "%d%d", &a1, &a2);                offer[i][a1]=a2;            }            fscanf(fin, "%d", &reduce[i]);        }        fscanf(fin, "%d", &n);        for(i=1; i<=n; i++)        {            fscanf(fin, "%d%d%d", &a[i].c, &a[i].k, &a[i].r);        }        d[0][0][0][0][0]=0;        for(a1=0;a1<=a[1].k;a1++)        for(a2=0;a2<=a[2].k;a2++)        for(a3=0;a3<=a[3].k;a3++)        for(a4=0;a4<=a[4].k;a4++)        for(a5=0;a5<=a[5].k;a5++)        {            d[a1][a2][a3][a4][a5]=a1*a[1].r+a2*a[2].r+a3*a[3].r+a4*a[4].r+a5*a[5].r;            for(i=1;i<=s;i++)            {                if(num[i]>n) continue;                b1=a1-offer[i][a[1].c];                b2=a2-offer[i][a[2].c];b3=a3-offer[i][a[3].c];                b4=a4-offer[i][a[4].c];b5=a5-offer[i][a[5].c];                if(b1<0||b2<0||b3<0||b4<0||b5<0) continue;                d[a1][a2][a3][a4][a5]=min(d[a1][a2][a3][a4][a5],d[b1][b2][b3][b4][b5]+reduce[i]);            }        }        fprintf(fout, "%d\n", d[a[1].k][a[2].k][a[3].k][a[4].k][a[5].k]);    fclose(fin);fclose(fout);return 0;}


0 0
原创粉丝点击