Educational Codeforces Round 106 (Rated for Div. 2) C. Minimum Grid Path 奇偶 + 思维

传送门

文章目录

题意:

给一个二维平面,起点在 ( 0 , 0 ) (0,0) (0,0),终点在 ( n , n ) (n,n) (n,n),每次只能往上和往右走,距离随意,总步数不超过 n n n,每一步有一个代价 c i c_i ci,定义从 ( 0 , 0 ) (0,0) (0,0) ( n , n ) (n,n) (n,n)总花费是 ∑ c i ∗ d i s t i \sum c_i*dist_i cidisti d i s t i dist_i disti是第 i i i步走的长度。

思路:

我们假设一共走了 k k k步,那么说明我们拐了 k − 1 k-1 k1个弯,设每次走的步为 d i s t 1 , d i s t 2 , d i s t 3 , . . . , d i s t k dist_1,dist_2,dist_3,...,dist_k dist1,dist2,dist3,...,distk,我们可以发现 d i s t 1 + d i s t 3 + . . . = n dist_1+dist_3+...=n dist1+dist3+...=n d i s t 2 + d i s t 4 + . . . = n dist_2+dist_4+...=n dist2+dist4+...=n,所以我们可以奇偶分开做就好啦。
分别统计一下奇数和偶数到当前位的 c i c_i ci最小值,让后让最小值走的步最多,其他的 d i s t i = 1 dist_i=1 disti=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;
}
/*

*/




猜你喜欢

转载自blog.csdn.net/m0_51068403/article/details/115064831