poj 1701

来源:互联网 发布:演唱会售票软件 编辑:程序博客网 时间:2024/05/21 06:30
这到题的通过率不高,首先难度在于推公式,再次是高精度,幸好这个题可以直接用__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;
===================
取最小值 方法二:
min = 1;
for(i = 1;i <= m;i++)
{
    floor[i] = up[i] + down[i];
      if(floor[i] < floor[min])
        min = i;
}

cout<<min<<endl;