Bear has a large, empty ground for him to build a home. He decides to build a row of houses, one after another, say nn in total.
The houses are designed with different height. Bear has mm workers in total, and the workers must work side by side. So at a time bear can choose some continuous houses, no more than mm, and add their heights by one, this takes one day to finish.
Given the designed height for each house, what is the minimum number of days after which all the houses’ heights are no less than the original design?
Standard Input
The first line of input contains a number TT, indicating the number of test cases. (Tleq 50T≤50)
For each case, the first line contains two integers nn and mm: the number of houses and the number of workers. The next line comes with nn non-negative numbers, they are the heights of the houses from left to right. (1leq n, mleq 100,0001≤n,m≤100,000, each number will be less than 1,000,000,0001,000,000,000)
Standard Output
For each case, output Case #i:
first. (ii is the number of the test case, from 11 to TT). Then output the days when bear’s home can be built.
Samples
Input | Output |
---|---|
2 3 3 1 2 3 3 3 3 2 1 |
Case #1: 3 Case #2: 3 |
Problem ID | 4 |
Problem Title | Complete Building the Houses |
Time Limit | 2000 ms |
Memory Limit | 64 MiB |
Output Limit | 64 MiB |
Source | The 11th UESTC Programming Contest Final |
这是一道贪心+差分的题目
贪心的思路是每次选择当前的最优策略,通过每一步的最优策略达到整体的最优。
特点是只考虑当下情况。
对于此题,既然每次最多能建的宽度是m,且建宽度1和建宽度m的花费是一样的,那么就一定每次建m。
现在考虑到通过最终的线性运算来实现一个区间的变换,所以用差分法。
看到洛谷上有一个评论:看到区间就想差分法。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <iostream> 9 #include "algorithm" 10 using namespace std; 11 typedef long long LL; 12 const int MAX=100005; 13 LL t,n,m,a[MAX],b[MAX]; 14 inline LL read(){ 15 LL an=0;char c;c=getchar(); 16 while (c<'0' || c>'9') c=getchar(); 17 while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();} 18 return an; 19 } 20 int main(){ 21 freopen ("4.in","r",stdin); 22 freopen ("4.out","w",stdout); 23 LL i,j,k,ant,ans; 24 scanf("%lld",&t); 25 for (k=1;k<=t;k++){ 26 n=read(),m=read(); 27 for (i=1;i<=n;i++) a[i]=read(); 28 memset(b,0,sizeof(b)); 29 ans=0; 30 for (i=1;i<=n;i++){ 31 b[i]+=b[i-1]; 32 if (b[i]<a[i]){ 33 ant=a[i]-b[i]; 34 ans+=ant; 35 b[i]+=ant; 36 if (i+m<=n) b[i+m]-=ant; 37 } 38 } 39 printf("Case #%lld: %lld ",k,ans); 40 } 41 return 0; 42 }