BestCoder Round #33

Go to movies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 491    Accepted Submission(s): 291


Problem Description
Winter holiday is coming!As the monitor, LeLe plans to go to the movies.
Because the winter holiday tickets are pretty expensive, LeLe decideds to try group-buying.
 
Input
There are multiple test cases, about 20 cases. The first line of input contains two integers n,m(1n,m100)n indicates the number of the students. mindicates how many cinemas have offered group-buying.

For the m lines,each line contains two integers ai,bi(1ai,bi100), indicating the choices of the group buying cinemas offered which means you can use biyuan to buy ai tickets in this cinema.
 
Output
For each case, please help LeLe **choose a cinema** which costs the least money. Output the total money LeLe should pay.
 
Sample Input
3 2 2 2 3 5
 
Sample Output
4
Hint
LeLe can buy four tickets with four yuan in cinema 1.
 
Source
解题思路:直接枚举去哪个电影院,从中取花费最少的,ans=min(n+ai1aibi)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #include<cstdlib>
 7 #include<stack>
 8 #include<math.h>
 9 using namespace std;
10 const int inf=0x3f3f3f3;
11 int m,n;
12 int ans;
13 int main()
14 {
15     while(~scanf("%d%d",&n,&m)){
16        ans=inf;
17        int sum;
18        int a,b;
19        for(int i=0;i<m;i++)
20        {
21            scanf("%d%d",&a,&b);
22            if(n%a==0){
23             sum=n/a*b;
24            }
25            else{
26             sum=(n/a+1)*b;
27            }
28            ans=min(ans,sum);
29        }
30        cout<<ans<<endl;
31     }
32     return 0;
33 }

Building Blocks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1809    Accepted Submission(s): 385


Problem Description
After enjoying the movie,LeLe went home alone. LeLe decided to build blocks.
LeLe has already built n piles. He wants to move some blocks to make W consecutive piles with exactly the same height H.

LeLe already put all of his blocks in these piles, which means he can not add any blocks into them. Besides, he can move a block from one pile to another or a new one,but not the position betweens two piles already exists.For instance,after one move,"3 2 3" can become "2 2 4" or "3 2 2 1",but not "3 1 1 3".

You are request to calculate the minimum blocks should LeLe move.
 

Input
There are multiple test cases, about 100 cases.

The first line of input contains three integers n,W,H(1n,W,H50000).n indicate n piles blocks.

For the next line ,there are n integers A1,A2,A3,,An indicate the height of each piles. (1Ai50000)

The height of a block is 1.
 

Output
Output the minimum number of blocks should LeLe move.

If there is no solution, output "-1" (without quotes).
 

Sample Input
4 3 2 1 2 3 5 4 4 4 1 2 3 4
 

Sample Output
1 -1
Hint
In first case, LeLe move one block from third pile to first pile.
 

Source
解题思路:
枚举最终的W堆积木在哪,确定了区间,那么就需要把高于H的拿走,低于H的补上,高处的积木放到矮的上面,这样最优。因此把这个区间变成W*H的代价就是max((HiH),(HHj))(HiH,HjH)即在把高的变矮和把矮的变高需要的移动的积木数
取较大的。从第一个区间[1,W]到第二区间[2,W+1]只是改变了2堆积木,可以直接对这两堆积木进行删除和添加来维护(HiH)(HHj)。
需要注意的是,最终选取的W堆积木中,有可能有几堆原本不存在。如 9 8 7 形成3*3,可把3堆积木变成5堆 3 3 3 8 7,最少移动6个积木。因此需要在n堆积木两端补上W个0。整个问题的复杂度是O(n+W).
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #include<cstdlib>
 7 #include<stack>
 8 #include<math.h>
 9 using namespace std;
10 const int inf=0x3f3f3f3;
11 const int maxn=150000;
12 long long n,w,h;
13 long long ans;
14 long long num[maxn+7];
15 int main()
16 {
17     int sum;
18     while(~scanf("%lld%lld%lld",&n,&w,&h)){
19         memset(num,0,sizeof(num));
20         ans=w*h;sum=0;
21         for(int i=1;i<=n;i++)
22         {
23             scanf("%d",&num[50000+i]);
24             sum+=num[50000+i];
25         }
26         if(sum<w*h){printf("-1
");continue;}
27         long long ans1=0,ans2=0;
28         for(int i=50001-w;i<=50000;i++)
29         {
30             if(num[i]>=h){
31                 ans1+=(num[i]-h);
32             }
33             else
34             {
35                 ans2+=(h-num[i]);
36             }
37         }
38         ans=min(ans,max(ans1,ans2));
39         for(int i=50001;i<=50000+n+w;i++)
40         {
41             if(num[i-w]>=h){
42                     ans1-=(num[i-w]-h);
43                 }
44             else{
45                     ans2-=(h-num[i-w]);
46                 }
47             if(num[i]>=h){
48                 ans1+=(num[i]-h);
49             }
50             else
51             {
52                 ans2+=(h-num[i]);
53             }
54             ans=min(ans,max(ans1,ans2));
55         }
56         printf("%lld
",ans);
57     }
58     return 0;
59 }
原文地址:https://www.cnblogs.com/codeyuan/p/4374084.html