积木大赛:
之前没有仔细地想,然后就直接暴力一点(骗点分),去扫每一高度,连到一起的个数,于是2组超时
先把暴力程序贴上来(可以当对拍机)
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 FILE *fin = fopen("block.in","r"); 5 FILE *fout= fopen("block.out","w"); 6 int *h; 7 int n; 8 int maxHeight = -1; 9 long long times = 0; 10 int main(){ 11 fscanf(fin,"%d",&n); 12 h = new int[(const int)(n + 1)]; 13 for(int i = 1;i <= n;i++){ 14 fscanf(fin,"%d",&h[i]); 15 if(h[i] > maxHeight) maxHeight = h[i]; 16 } 17 char isNew = 0x00; 18 for(int i = 1;i <= maxHeight;i++){ 19 isNew = 0x00; 20 for(int j = 1;j <= n;j++){ 21 if(h[j] >= i && isNew == 0){ 22 times++; 23 isNew = 0x01; 24 } 25 if(h[j] < i && isNew== 0x01){ 26 isNew = 0x00; 27 } 28 } 29 } 30 fprintf(fout,"%ld",times); 31 }
然而用样例来举个例子
*
* *
* * * *
* * * * *
-----------------------------
1 2 3 4 5
当第i列的目标高度比第(i-1)高的时候,很容易发现,需要多耗费(h[i]-h[i - 1])次操作,因为在操作使第(i-1)列达到目标高度时,第i列和目标高度还差
(h[i]-h[i - 1]),每次只能放一层的积木,所以需要多耗费(h[i]-h[i - 1])次操作。
例如把第一层放满,其它层还需要的高度
*
* * *
-----------------------------
1 2 3 4 5
这样会很奇怪,为什么第5列还需要放一次呢?那是因为第一次方的区间是[1,5],每次求差相当于把这一块连续的这一块放上积木
从图中可以看出如果h[i] <= h[i - 1]则不用处理,于是我们可以得到如下递推式
|- f[i - 1] ( h[i] <= h[i - 1] ) f[i]=| |- f[i - 1] + ( h[i]-h[i - 1] ) ( h[i] > h[i - 1] )
最后,附上代码,说明长,代码不长:
1 #include<iostream> 2 #include<fstream> 3 using namespace std; 4 ifstream fin("block.in"); 5 ofstream fout("block.out"); 6 int buffer[2]; 7 int n; 8 long long result = 0; 9 int main(){ 10 fin>>n; 11 for(int i = 1;i <= n;i++){ 12 fin>>buffer[1]; 13 if( buffer[1] > buffer[0] ) result += buffer[1] - buffer[0]; 14 buffer[0] = buffer[1]; 15 } 16 fout<<result; 17 return 0; 18 }