zoukankan      html  css  js  c++  java
  • 背包问题(01背包/完全背包/多重背包)

            对背包的解释        请看 DD神牛2013最新的背包九讲.pdf

    (01背包)例题和模板

    Problem Description

    Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
    The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
     

    Input

    The first line contain a integer T , the number of cases.
    Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

    Output

    One integer per line representing the maximum of the total value (this number will be less than 231).

    Sample Input

    1
    5 10
    1 2 3 4 5
    5 4 3 2 1

    Sample Output

    14
    
    
    
    
     1 #include<iostream>
     2 using namespace std;
     3 
     4 struct bone
     5 {
     6     int value;
     7     int volume;
     8 }b[1005];
     9 
    10 int max(int a,int b)
    11 {
    12     return a>b?a:b;
    13 }
    14 
    15 int main()
    16 {
    17     int t,n,v,i,j,f[1001];
    18     cin>>t;
    19     while(t--)
    20     {
    21         scanf("%d%d",&n,&v);
    22         for(i=0;i<n;i++)
    23             scanf("%d",&b[i].value);
    24         for(i=0;i<n;i++)
    25             scanf("%d",&b[i].volume);
    26         for(i=0;i<=v;i++)
    27             f[i]=0;
    28         for(i=0;i<n;i++)
    29             for(j=v;j>=b[i].volume;j--)
    30                 f[j]=max(f[j],f[j-b[i].volume]+b[i].value);
    31         cout<<f[v]<<endl;
    32     }
    33     return 0;
    34 }
    View Code

    (多重背包)例题和模板

    Problem Description

    急!灾区的食物依然短缺!
    为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
    请问:你用有限的资金最多能采购多少公斤粮食呢?

    后记:
    人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
    月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
    感谢父母,他们给予我们生命,抚养我们成人;
    感谢老师,他们授给我们知识,教我们做人
    感谢朋友,他们让我们感受到世界的温暖;
    感谢对手,他们令我们不断进取、努力。
    同样,我们也要感谢痛苦与艰辛带给我们的财富~
     

    Input

    输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。

    Output

    对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。

    Sample Input

    1
    8 2
    2 100 4
    4 100 2
    

    Sample Output

    400
    
     1 #include<iostream>
     2 using namespace std;
     3 
     4 int n,v,f[50001];
     5 bool make(int wi,int ci)
     6 {
     7     bool bk=1;
     8     for(int j=v;j>=wi;--j)
     9         if(f[j]<f[j-wi]+ci)
    10         {
    11             f[j]=f[j-wi]+ci;
    12             bk=0;
    13         }
    14     return bk;
    15 }
    16 int main()
    17 {
    18     int t;
    19     scanf("%d",&t);
    20     while(t--)
    21     {
    22     scanf("%d%d",&v,&n);
    23     
    24     memset (f,0,sizeof(f));
    25     for(int i=1;i<=n;++i)
    26     {
    27         int k,w,c;
    28         scanf("%d%d%d",&w,&c,&k);
    29         int t=1;
    30         bool bo=0;
    31         while(t<=k)
    32         {
    33              bo=make(t*w,t*c);
    34              if(bo) break;
    35              k-=t;
    36              t*=2;
    37         }
    38         if(bo) continue;
    39         if(k) make(k*w,k*c);
    40     }
    41     printf("%d\n",f[v]);
    42     }
    43     return 0;
    44 }
    View Code

    (完全背包)

    Problem Description

    在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。

    Input

    每行只有一个正整数N,N小于32768。

    Output

    对应每个输入,输出兑换方法数。

    Sample Input

    2934
    12553
    

    Sample Output

    718831
    13137761
    
     1 #include<iostream>
     2 using namespace std ;
     3 
     4 int main()
     5 {
     6     int n,i,j;
     7     int dp[35000];
     8     memset(dp,0,sizeof(dp));
     9     dp[0]=1;
    10 
    11     for(i=1;i<=3;i++)
    12         for(j=i;j<35000;j++)
    13             dp[j]+=dp[j-i];
    14         while(scanf("%d",&n)!=EOF)
    15         {
    16             printf("%d\n",dp[n]);
    17         }
    18         return 0 ;
    19 }  
    View Code

    ---------------------------------------------------------------------------------------

           其他的题目 基本上都是在背包的基础之上进行了小小的改造

     ------------------------------------------------------------------------------------------

    Problem Description

    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
    某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

    Input

    多组数据。对于每组数据:
    第一行为正整数n,表示菜的数量。n<=1000。
    第二行包括n个正整数,表示每种菜的价格。价格不超过50。
    第三行包括一个正整数m,表示卡上的余额。m<=1000。

    n=0表示数据结束。

    Output

    对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。

    Sample Input

    1
    50
    5
    10
    1 2 3 2 1 1 2 3 2 1
    50
    0
    

    Sample Output

    -45
    32
    
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int max(int a, int b)
     8 {
     9     return a>b?a:b;
    10 }
    11 int main()
    12 {
    13     int i,j,k;
    14     int t,n,m;
    15     int maxn;
    16     int dp[2014]={0},price[2014]={0};
    17     while(scanf("%d",&n)!=EOF,n)
    18     {
    19         memset(price,0,sizeof(price));
    20         memset(dp,0,sizeof(dp));
    21         for(i=1;i<=n;i++)
    22         {
    23             cin>>price[i];
    24         }
    25         cin>>m;
    26         if(m<5)
    27         {
    28             printf("%d\n",m);
    29             continue;
    30         }
    31         sort(price+1,price+n+1);
    32         maxn=price[n];
    33         m=m-5;
    34         for(i=1;i<n;i++)
    35         {
    36             for(j=m;j>=price[i];j--)
    37             {
    38                 dp[j]=max(dp[j],dp[j-price[i]]+price[i]);
    39             }
    40         }
    41         printf("%d\n",m+5-dp[m]-maxn);
    42     }
    43     return 0;
    44 }
    View Code

    Problem Description

    The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university.
     
    For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.


    His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.

    Input

    The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj .
    Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .

    Output

    For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

    Notes and Constraints
    0 < T <= 100
    0.0 <= P <= 1.0
    0 < N <= 100
    0 < Mj <= 100
    0.0 <= Pj <= 1.0
    A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.

    Sample Input

    3
    0.04 3
    1 0.02
    2 0.03
    3 0.05
    0.06 3
    2 0.03
    2 0.03
    3 0.05
    0.10 3
    1 0.03
    2 0.02
    3 0.05

    Sample Output

    2
    4
    6
    
    
    
    
    
    
     1 #include <stdio.h>
     2 #define max(a,b) (a>b?a:b)
     3 
     4 int main()
     5 {
     6     int t,num,v;
     7     double sum,gl[105],f[10005];
     8     int val[105];
     9     while (scanf("%d",&t)!=EOF)
    10     {
    11         while (t--)
    12         {
    13             v = 0;
    14             scanf("%lf%d",&sum,&num);
    15             for(int i = 0;i < num; i++)
    16             {
    17                 scanf("%d%lf",&val[i],&gl[i]);
    18                 v += val[i];
    19             }
    20             f[0] = 1.0;
    21             for(i=1;i<=v;i++)
    22                 f[i] = 0.0;
    23             for(i = 0;i<num;i++)
    24             {
    25                 for (int j=v;j>=val[i];j--)
    26                 {
    27             f[j]=max(f[j],f[j-val[i]]*(1-gl[i]));
    28                 }
    29             }
    30             for(i=v;i>=0;i--)
    31             {
    32                 if(f[i]>=(1-sum))
    33                 {
    34                 printf("%d\n",i);
    35                     break;
    36                 }
    37             }
    38         }
    39     }
    40     return 0;
    41 }
    View Code

    Problem Description

    Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。

    Input

    输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000)
    后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。
    输入的最后有两个0。

    Output

    每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。

    Sample Input

    10 3
    4 0.1
    4 0.2
    5 0.3
    0 0
    

    Sample Output

    44.0%
    

    Hint

    You should use printf("%%") to print a '%'.
     
     
     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define V 11111
     5 #define N 1111
     6 #define MAX(x,y) ((x)>(y)?(x):(y))
     7 using namespace std;
     8 
     9 double dp[V]; 
    10 int c[N];      //每所学校花的钱
    11 double w[N];   //概率
    12 
    13 int main()
    14 {    
    15     int n,v,i,j;
    16     while(~scanf("%d%d",&v,&n))
    17     {
    18         if(v==0&&n==0)break;
    19         for(i=0;i<n;i++)
    20         {
    21             scanf("%d%lf",&c[i],&w[i]);
    22         }
    23     memset(dp,0,sizeof(double)*(v+1));  //double型的初始化
    24         for(i=0;i<n;i++)
    25         {
    26             for(j=v;j>=c[i];j--) 
    27                 dp[j] = MAX(dp[j],w[i]+(1.0-w[i])*dp[j-c[i]]);//动态方程
    28         }
    29         printf("%.1lf%%\n",dp[v]*100);
    30     }
    31     return 0;
    32 }
    View Code

    Problem Description

    When Teddy was a child , he was always thinking about some simple math problems ,such as “What it’s 1 cup of water plus 1 pile of dough ..” , “100 yuan buy 100 pig” .etc..

    One day Teddy met a old man in his dream , in that dream the man whose name was“RuLai” gave Teddy a problem :

    Given an N , can you calculate how many ways to write N as i * j + i + j (0 < i <= j) ?

    Teddy found the answer when N was less than 10…but if N get bigger , he found it was too difficult for him to solve.
    Well , you clever ACMers ,could you help little Teddy to solve this problem and let him have a good dream ?

    Input

    The first line contain a T(T <= 2000) . followed by T lines ,each line contain an integer N (0<=N <= 1010).

    Output

    For each case, output the number of ways in one line.

    Sample Input

      2
      1
      3

    Sample Output

    0
    1
    
    
    
    
     1 #include<iostream>
     2 
     3 using namespace std ;
     4 
     5 int main()
     6 {
     7 
     8     __int64 n,i,sum;
     9     int t;
    10     scanf("%d",&t);
    11     while(t--)
    12     {
    13         scanf("%I64d",&n);
    14         sum = 0 ;
    15         for(i=1;(i+1)*(i+1)<=(n+1);i++)
    16         {
    17             if((n+1)%(i+1)==0)
    18                 sum++;
    19         }
    20             printf("%I64d\n",sum);
    21     }
    22 
    23     return 0;
    24 }
    View Code

    Problem Description

    Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid.

    But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs!

    Input

    The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000. On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency. Following this are exactly N lines, each specifying one coin type. These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000). P is the value of the coin in monetary units, W is it's weight in grams.

    Output

    Print exactly one line of output for each test case. The line must contain the sentence "The minimum amount of money in the piggy-bank is X." where X is the minimum amount of money that can be achieved using coins with the given total weight. If the weight cannot be reached exactly, print a line "This is impossible.".

    Sample Input

    3
    10 110
    2
    1 1
    30 50
    10 110
    2
    1 1
    50 30
    1 6
    2
    10 3
    20 4
    

    Sample Output

    The minimum amount of money in the piggy-bank is 60.
    The minimum amount of money in the piggy-bank is 100.
    This is impossible.
    

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #define INF 0xfffffff
     4 int dp[10010];
     5 int min(int x,int y)
     6 {
     7     return x>y?y:x;
     8 }
     9 int main()
    10 {
    11     int t,e,f,n,m,p,w,i,j;
    12     scanf("%d",&t);
    13     while(t--)
    14     {
    15         scanf("%d%d",&e,&f);
    16         m=f-e;
    17         for(i=1;i<=m;i++)
    18             dp[i]=INF;
    19         dp[0]=0;
    20         scanf("%d",&n);
    21         for(i=0;i<n;i++)
    22         {
    23             scanf("%d%d",&p,&w);
    24             for(j=w;j<=m;j++)  //与01背包相比倒过来 
    25             {
    26                 dp[j]=min(dp[j],dp[j-w]+p);
    27             }
    28         }
    29         if(dp[m]==INF)
    30            printf("This is impossible.\n");
    31         else
    32         {
    33 printf("The minimum amount of money in the piggy-bank is ");
    34         printf("%d.\n",dp[m]);
    35         }
    36     }
    37     return 0;
    38 }
    View Code
     

    Problem Description

    "Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says.

    "The second problem is, given an positive integer N, we define an equation like this:
      N=a[1]+a[2]+a[3]+...+a[m];
      a[i]>0,1<=m<=N;
    My question is how many different equations you can find for a given N.
    For example, assume N is 4, we can find:
      4 = 4;
      4 = 3 + 1;
      4 = 2 + 2;
      4 = 2 + 1 + 1;
      4 = 1 + 1 + 1 + 1;
    so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"

    Input

    The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.

    Output

    For each test case, you have to output a line contains an integer P which indicate the different equations you have found.

    Sample Input

    4
    10
    20
    

    Sample Output

    5
    42
    627
    
     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 int a[123],b[123];
     7 
     8 int main()
     9 {
    10     int i,j,k;
    11     for(i=0;i<=120;i++)
    12         a[i]=b[i]=1;
    13     for(k=2;k<=120;k++)
    14     {
    15         for(j=k;j<=120;j+=k)  //母函数基本模板
    16              for(i=0;i+j<=120;i++)
    17                    a[i+j]+=b[i];
    18       for(i=0;i<=120;i++)
    19               b[i]=a[i];
    20     }
    21 while(scanf("%d",&i)!=EOF)
    22    printf("%d\n",a[i]);
    23  return 0;
    24 }
    View Code

    (ps:此题用的是 母函数)

    Problem Description

    不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前.

    死亡骑士:"我要买道具!"

    地精商人:"我们这里有三种道具,血瓶150块一个,魔法药200块一个,无敌药水350块一个."

    死亡骑士:"好的,给我一个血瓶."

    说完他掏出那张N元的大钞递给地精商人.

    地精商人:"我忘了提醒你了,我们这里没有找客人钱的习惯的,多的钱我们都当小费收了的,嘿嘿."

    死亡骑士:"......"

    死亡骑士想,与其把钱当小费送个他还不如自己多买一点道具,反正以后都要买的,早点买了放在家里也好,但是要尽量少让他赚小费.

    现在死亡骑士希望你能帮他计算一下,最少他要给地精商人多少小费.

    Input

    输入数据的第一行是一个整数T(1<=T<=100),代表测试数据的数量.然后是T行测试数据,每个测试数据只包含一个正整数N(1<=N<=10000),N代表死亡骑士手中钞票的面值.

    注意:地精商店只有题中描述的三种道具.

    Output

    对于每组测试数据,请你输出死亡骑士最少要浪费多少钱给地精商人作为小费.

    Sample Input

    2
    900
    250
    

    Sample Output

    0
    50
    

     1 #include<iostream>
     2 
     3 using namespace std ;
     4 
     5 int main()
     6 {
     7     int t,i,j,k,max,n,temp;
     8     scanf("%d",&t);
     9     while(t--)
    10     {
    11         scanf("%d",&n);
    12         max=0;
    13         for(i=0;i<=n/350;i++)
    14             for(j=0;j<=n/200;j++)
    15                 for(k=0;k<=n/150;k++)
    16                 {
    17                     temp=i*350+j*200+k*150;
    18                     if(temp<=n)
    19                     {
    20                     if(temp>max)max=temp;
    21                     }
    22                 }
    23                 printf("%d\n",n-max);
    24     }
    25     return 0 ;
    26 }
    View Code

    (ps:此题直接暴力求解了  ⊙﹏⊙)

    Problem Description

    People in Silverland use square coins. Not only they have square shapes but also their values are square numbers. Coins with values of all square numbers up to 289 (=17^2), i.e., 1-credit coins, 4-credit coins, 9-credit coins, ..., and 289-credit coins, are available in Silverland.
    There are four combinations of coins to pay ten credits:

    ten 1-credit coins,
    one 4-credit coin and six 1-credit coins,
    two 4-credit coins and two 1-credit coins, and
    one 9-credit coin and one 1-credit coin.

    Your mission is to count the number of ways to pay a given amount using coins of Silverland.

    Input

    The input consists of lines each containing an integer meaning an amount to be paid, followed by a line containing a zero. You may assume that all the amounts are positive and less than 300.

    Output

    For each of the given amount, one line containing a single integer representing the number of combinations of coins should be output. No other characters should appear in the output.

    Sample Input

    2
    10
    30
    0
    

    Sample Output

    1
    4
    27
    
     1 #include<iostream>
     2 
     3 using namespace std ;
     4 
     5 int num[20],dp[300];
     6 
     7 void  init()
     8 {
     9     int i;
    10     for(i=1;i<=17;i++)
    11         num[i]=i*i;
    12 }
    13 
    14 void sum(int x)
    15 {
    16     int i,j;
    17     for(i=1;i<=17;i++)
    18     {
    19     if(x>=num[i])
    20             for(j=num[i];j<=x;j++)
    21                 dp[j]+=dp[j-num[i]];
    22 
    23     }
    24     cout<<dp[x]<<endl;
    25 }
    26 int main()
    27 {
    28     init();
    29     int n;
    30     while(scanf("%d",&n)!=EOF&&n)
    31     {
    32         memset(dp,0,sizeof(dp));
    33         dp[0]=1;
    34         sum(n);
    35     }
    36     return 0 ;
    37 
    38 }
    View Code

    Problem Description

    Ignatius drinks milk everyday, now he is in the supermarket and he wants to choose a bottle of milk. There are many kinds of milk in the supermarket, so Ignatius wants to know which kind of milk is the cheapest.

    Here are some rules:
    1. Ignatius will never drink the milk which is produced 6 days ago or earlier. That means if the milk is produced 2005-1-1, Ignatius will never drink this bottle after 2005-1-6(inclusive).
    2. Ignatius drinks 200mL milk everyday.
    3. If the milk left in the bottle is less than 200mL, Ignatius will throw it away.
    4. All the milk in the supermarket is just produced today.

    Note that Ignatius only wants to buy one bottle of milk, so if the volumn of a bottle is smaller than 200mL, you should ignore it.
    Given some information of milk, your task is to tell Ignatius which milk is the cheapest.

    Input

    The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
    Each test case starts with a single integer N(1<=N<=100) which is the number of kinds of milk. Then N lines follow, each line contains a string S(the length will at most 100 characters) which indicate the brand of milk, then two integers for the brand: P(Yuan) which is the price of a bottle, V(mL) which is the volume of a bottle.

    Output

    For each test case, you should output the brand of the milk which is the cheapest. If there are more than one cheapest brand, you should output the one which has the largest volume.

    Sample Input

    2
    2
    Yili 10 500
    Mengniu 20 1000
    4
    Yili 10 500
    Mengniu 20 1000
    Guangming 1 199
    Yanpai 40 10000
    

    Sample Output

    Mengniu
    Mengniu
    

    Hint

    In the first case, milk Yili can be drunk for 2 days, it costs 10 Yuan. Milk Mengniu can be drunk for 5 days, it costs 20 Yuan. So Mengniu is the cheapest.In the second case,
    milk Guangming should be ignored. Milk Yanpai can be drunk for 5 days, but it costs 40 Yuan. So Mengniu is the cheapest.
     
     1 #include<iostream>
     2 #include<cstring>
     3 
     4 using namespace std;
     5 
     6 #define MaxInt 0x3f3f3f3f 
     7 
     8 
     9 struct milk
    10 {
    11     char s[105];//brand
    12     int p; //price
    13     double pp;//per price
    14     int v;//volume 
    15     int d;//days
    16 }m[105];
    17 
    18 int main()
    19 {
    20     int t,n,i;
    21     scanf("%d",&t);
    22     while(t--)
    23     {
    24         
    25         scanf("%d",&n);
    26     
    27         m[0].v=0;
    28         m[0].pp=MaxInt;
    29     
    30         for(i=1;i<=n;i++)
    31         {
    32         scanf("%s%d%d",m[i].s,&m[i].p,&m[i].v);
    33             if(m[i].v>=200)
    34             {
    35                 m[i].d=m[i].v/200;
    36                 if(m[i].d>5)m[i].d=5;
    37             m[i].pp=((double)m[i].p)/(m[i].d);
    38                 
    39 
    40                 if(m[i].pp<m[0].pp)
    41                 {
    42                     strcpy(m[0].s,m[i].s);
    43                 m[0].pp=m[i].pp;
    44                 m[0].v=m[i].v;
    45                 }
    46             else if(m[i].pp==m[0].pp)
    47                 {
    48                 if(m[i].v>m[0].v)
    49                     {
    50                         strcpy(m[0].s,m[i].s);
    51                 m[0].pp=m[i].pp;
    52                 m[0].v=m[i].v;
    53                     }
    54 
    55                 }
    56             }
    57         }
    58         printf("%s\n",m[0].s);
    59     }
    60     return 0;
    61 }
    View Code

    (原谅我     我真是太暴力了。。。。)

    (这道题中说  Ignatius will never drink the milk which is produced 6 days ago or earlier     一开始我认为可以喝6天  结果wa了好几次    ╮(╯▽╰)╭    改成5就对了)


  • 相关阅读:
    向工信部投诉中国联通、移动、电信等运营服务商的权威途径
    如何把本机Sql Sever数据库转移到虚拟主机sql数据库
    SQL Server 2005如何远程连接数据库?
    mssql server 2005还原数据库bak文件与“备份集中的数据库备份与现有的xx数据库不同”解决方法
    傲游5里保存的网址,在傲游4不能同步?外加几句吐槽
    mysql数据库基础的简单操作指南
    MVC框架模式技术实例(用到隐藏帧、json、仿Ajax、Dom4j、jstl、el等)
    Web---JSTL(Java标准标签库)-Core核心标签库、I18N国际化、函数库
    Jupyter Notebook导入自定义模块时ImportError
    Pandas数据处理(2): 数据透视表,行转列、列转行、以及一行生成多行
  • 原文地址:https://www.cnblogs.com/ws5167/p/3893677.html
Copyright © 2011-2022 走看看