3 solutions
-
3
边打边移的作用:移动后,攻击后续每个位置的攻击距离变短
但是攻击花费变少的同时移动的花费要变多
所以我的做法是计算每个点:假如攻城炮最终移动到这个点,我们的总花费是多少
然后比较出最小花费
然后就要想,假如我们要移动到这个位置,花费怎么算好算呢
我们很容易想到,要移动到某个点,一定是边打边移动花费最小,如果一直打到那个点再移动过去是比较亏的
变打边移动的话,移动的花费就是b*该点的位置
而这个点以前的攻击花费就是a该点位置(假如移到a3点,攻击距离=(a1-0+a2-a1+a3-a2)=a3),该点以后的攻击总距离=a4-a3+a5-a3+a6-a3+...+an-a3=(a4+a5+a6+...+an)-(a3(n-3)),而a4+a5+...+an=总前缀和-(a1+a2+a3)=总前缀和-第三个点的前缀和
OK,上代码:
#include<stdio.h> int x[200000]; long long y[200000]; int main() { int t; scanf("%d",&t); long long n,a,b; int i; long long num,num2,ans; while(t--) { num=0; scanf("%lld %lld %lld",&n,&a,&b); for(i=0;i<n;i++) { scanf("%d",&x[i]); num+=x[i]; y[i]=num;//记录每个点的前缀和 } ans=num*b; for(i=0;i<n-1;i++) { num2=(x[i]+num-y[i]-(n-i-1)*x[i])*b+x[i]*a; //计算如果最终移动到当前点位,移动和攻击的总花费是多少 //x[i]为该点之前的总攻击距离,num为总前缀和,y[i]为该点的前缀和 //n-i-1为该点之后攻击的次数,因为每次攻击都要少一个x[i]的攻击距离 if(num2<ans)ans=num2; } printf("%lld\n",ans); } return 0; }
Information
- ID
- 839
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 8
- Tags
- # Submissions
- 68
- Accepted
- 9
- Uploaded By