ACM---Dissatisfying Lift

Dissatisfying Lift

Time Limit: 1000ms, Special Time Limit:2000ms, Memory Limit:65536KB
Total submit users: 1524, Accepted users: 1048
Problem 10003 : No special judgement

Problem description

There’s a building with M floors. The amounts of tenants of every floor are K1, K2, K3, …, Km. One day all the tenants went home together and they took the same lift (suppose the lift was large enough). Because of some reason the lift could only stop on one floor and the tenants must go upstairs or downstairs to their houses. Every tenant went up N floors would make the dissatisfied degree rise N * a + 0.5 * N * (N - 1) degrees, and every tenant went down N floors would make the dissatisfied degree rise N * b + 0.5 * N * (N - 1) degrees. Your task is to tell which floor the lift should stop, in order to make the dissatisfied degree as low as possible.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each test contains M (1 <= M <= 10000), a and b (0 <= a, b <= 100). The second line contains K1, K2, K3, …, Km(0 <= Ki <= 20, i = 1…M).

Output

For each test case, print a line containing a single integer, indicating which floor the lift should stop.

Sample Input

1
5 3 2
1 1 1 1 1

Sample Output

3

Judge Tips

Dynamic Programming

分析

采用两个数组分别计算储存在某层停留,需要上下的不满意度是多少(up and down)
这样的话,就需要探讨,每升(降)一层,他们之间满意度的变化规律,总结起来就是:
每升一层:(为方便分析,分开解说)
①就式子N * a而言,up[i]=up[i-1]+(在i层停留以前的人数)a;
②就式子0.5 * N * (N - 1)而言,up[i]=up[i-1]+(x1
(i-2)+x2*(i-3)+x3*(i-4)…)
(x1,x2,x3表示第1 2 3层的人,要保证i-数字>=0)

②式子的由来:
先分析一个人跨域层数的不满意度的情况:
跨越0层–0
跨越1层–0
跨越2层–1
跨越3层–3
跨越4层–6
跨越5层–10
跨越6层–15
那么,每升一层,一个人不满意度的变化:
由需要跨越一层到需要跨越两层 相差:1
由需要跨越2层到需要跨越3层 相差:2
由需要跨越3层到需要跨越4层 相差:3
由需要跨越4层到需要跨越5层 相差:4
由需要跨越5层到需要跨越6层 相差:5

假设x1,表示第1层的人,那么上述表达改为:
先分析第一层跨域层数的不满意度的情况:
跨越0层–0
跨越1层–0
跨越2层–1x1
跨越3层–3
x1
跨越4层–6x1
跨越5层–10
x1
跨越6层–15x1
那么,每升一层,第一层的人不满意度的变化:
由需要跨越一层到需要跨越两层 相差:1
x1
由需要跨越2层到需要跨越3层 相差:2x1
由需要跨越3层到需要跨越4层 相差:3
x1
由需要跨越4层到需要跨越5层 相差:4x1
由需要跨越5层到需要跨越6层 相差:5
x1

再加上x2,x3,x4…第2 3 4…层的人:
电梯停留在第3层,相比停留在第2层(第一层由需要跨越1层变为跨越两层):式子加上x1
电梯停留在第4层,相比停留在第3层:式子加上x12+x2
电梯停留在第5层,相比停留在第4层:式子加上x1
3+x2*2+x3
即,每次都是在上一次的差上加上sum0(人数)

代码如下

#include<iostream>
using namespace std;
__int64 num[10005],up[10005],down[10005];
int main(){
	int t;
	cin>>t;
	while(t--){
		int m,a,b;
		cin>>m>>a>>b;
		for(int i=1;i<=m;i++){
			cin>>num[i]; 
		}
		
		up[1]=0;
		int  sum0=num[1];//记录人数
		int sum1=0;//每层上升,式子第二部分的差 
		for(int i=2;i<=m;i++){
			up[i]=up[i-1]+b*sum0+sum1;
			sum1+=sum0;
			sum0+=num[i]; 
		}
		
		down[m]=0;
		sum0=num[m];
		sum1=0;
		for(int i=m-1;i>=1;i--){
			down[i]=down[i+1]+a*sum0+sum1;
			sum1+=sum0;
			sum0+=num[i];
		}
		__int64 mymin=up[1]+down[1];
		int k=1;
		for(int i=1;i<=m;i++){
			if(up[i]+down[i]<mymin){
				mymin=up[i]+down[i];
				k=i;
			}
		}
		cout<<k<<endl;
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MORE_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值