传送门
文章目录
- 题意:
- 思路:
题意:
给一个二维平面,起点在(0,0)(0,0)(0,0),终点在(n,n)(n,n)(n,n),每次只能往上和往右走,距离随意,总步数不超过nnn,每一步有一个代价cic_ici,定义从(0,0)(0,0)(0,0)到(n,n)(n,n)(n,n)总花费是∑ci∗disti\sum c_i*dist_i∑ci∗disti,distidist_idisti是第iii步走的长度。
思路:
我们假设一共走了kkk步,那么说明我们拐了k−1k-1k−1个弯,设每次走的步为dist1,dist2,dist3,...,distkdist_1,dist_2,dist_3,...,dist_kdist1,dist2,dist3,...,distk,我们可以发现dist1+dist3+...=ndist_1+dist_3+...=ndist1+dist3+...=n,dist2+dist4+...=ndist_2+dist_4+...=ndist2+dist4+...=n,所以我们可以奇偶分开做就好啦。
分别统计一下奇数和偶数到当前位的cic_ici最小值,让后让最小值走的步最多,其他的disti=1dist_i=1disti=1即可。
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n;
int c[N];int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);int _; scanf("%d",&_);while(_--){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&c[i]);LL pre1,pre2,ans1,ans2;pre1=pre2=0;ans1=ans2=1e18;LL ans=1e18;LL mi1,mi2; mi1=mi2=1e18;for(int i=1,c1=0,c2=0;i<=n;i++){if(i%2==1){mi1=min(mi1,1ll*c[i]);c1++;pre1+=c[i];if(i>=2) ans=min(ans,1ll*(n-c1)*mi1+pre1+ans2);ans1=1ll*(n-c1)*mi1+pre1;}else{mi2=min(mi2,1ll*c[i]);c2++;pre2+=c[i];if(i>=2) ans=min(ans,1ll*(n-c2)*mi2+pre2+ans1);ans2=1ll*(n-c2)*mi2+pre2;}}printf("%lld\n",ans);}return 0;
}
/**/