推公式:POJ 1701 Dissatisfying Lift
这到题的通过率不高,首先难度在于推公式,再次是高精度,幸好这个题可以直接用__int64,就过了。
下午看到这道题的时候,比较懒,想直接一个个遍历,求出下楼的不满总数&上楼的不满总数,时间复杂是O(N^2);而且没有考虑道高精度,所以直接就WA和TLE了。
推导如下:
令: pi = f[1] + f[2] ...... f[i]
down[0] = 0;
down[i+1] = down[i] + b*pi + (p1+p2 ....+ pi-1);
qi = f[m] + f[m-1] + ...f[m-i];
up[m] = 0;
up[i-1] = up[i] + a* qi + (q1 + q2 ...+qi-1);
这个公式的和行就是后面的求和部分,(q1 + q2 ...+qi-1);这个也是我用两个求差,无意中发现的,
f[1]
f[1] f[2]
f[1] f[2] f[3]
f[1] f[2] f[3] f[4]
......................................
回来花了20分钟写出了代码,出现了2个WA,是因为我的min值设的不够大,取道99999999999999999,就过了。
代码如下:
#i nclude <iostream>
using namespace std;
const int MAX = 10001;
int f[MAX];
__int64 down[MAX],up[MAX],min;
int main()
{
int t,m,a,k, b;
cin>>t;
while(t--)
{
memset(f,0,sizeof(f));
memset(down,0,sizeof(down));
memset(up,0,sizeof(up));
cin>>m>>a>>b;
for(int i=1; i<=m; i++)
{
cin>>k;
f[i] = k;
}
__int64 p=f[1],q=f[m], sum = 0;
int besti = -1;
down[1] = 0;
for(i=2; i<=m; i++)
{
down[i] = down[i-1]+b*p+sum;
sum += p;
p += f[i];
}
sum = 0; up[m] = 0;
for(i=m-1; i>=1; i--)
{
up[i] = up[i+1]+a*q+sum;
sum += q;
q += f[i];
}
min=999999999999999;
for(i=1; i<=m; i++)
{
if(min>(down[i]+up[i]) )
{
min = down[i]+up[i];
besti = i;
}
}
cout<<besti<<endl;
}
return 0;