首页 > 其他分享 >nove.12 跳跳

nove.12 跳跳

时间:2022-11-12 10:34:01浏览次数:97  
标签:nove.12 ch 跳跳 cdots long int while now

跳跳
以为是个最长路,结果是个贪心
高度排序,然后每次跳高度差最大的点即可

网上找了个证明,想法很好但是没说清楚,应该是这样的:
要证明每次跳高度差最大的点最优,那么证明其中一次就行了,那么证明第一次
不妨设\(0=h_0<h_1<\cdots<h_n\),假设第一次跳到\(h_p\)最优
第一次跳到\(h_p\),如果最后一次跳到\(h_n\),把这个过程反过来,即
\(h_0\to h_p \to h_{x1}\to h_{x2} \to \cdots \to h_{xi}\to h_n\)变为\(h_0\to h_n \to h_{xi}\to h_{x(i-1)} \to \cdots \to h_{x1}\to h_p\)
两种跳法的差异仅在于第一跳,反过来后体力值增加\(-h_p^2+h_n^2\)当\(h_p<h_n\)时体力值不最优
所以第一次跳到\(h_n\)最优
另一种情况,最后一次没有跳到\(h_n\),不妨设\(h_n\)之后跳到\(h_q\)
相同地进行反转操作:\(h_0\to h_p \to h_{x1}\to h_{x2} \to \cdots \to h_{xi}\to h_n\to h_q\to \cdots\)变为\(h_0\to h_n \to h_{xi}\to h_{x(i-1)} \to \cdots \to h_{x1}\to h_p\to h_q\to \cdots\)
体力值增加\(-[h_p^2+(h_n-h_q)^2]+[h_n^2+(h_p-h_q)^2]=2h_nh_q-2h_ph_q\)
当\(h_p<h_n\)时体力值不最优,即此种情况下第一次跳到\(h_n\)也是最优
综上,第一次跳到\(h_n\)总是最优,证毕

最后发现贪心、最长路都是对的,只不过要开long long

最长路

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long

int in{
    int i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

const int N=1e3+5;
int n,h[N],dis[N];
vector<int>G[N];
priority_queue<pair<int,int> >q;
bool vis[N];

void Dijkstra(){
    q.push(make_pair(dis[0],0));
    while(!q.empty()){
        int u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=true;
        for(int v=0;v<=n;++v){
            if(u==v) continue;
            int w=G[u][v];
            if(dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                q.push(make_pair(dis[v],v));
            }
        }
    }
}

signed main(){

    // freopen("1.in","r",stdin);

    n=in;
    for(int i=1;i<=n;++i) h[i]=in;

    for(int i=0;i<=n;++i)
        for(int j=0;j<=n;++j){
            int w=(h[i]-h[j])*(h[i]-h[j]);
            G[i].push_back(w);
        }
    
    Dijkstra();

    int ans=dis[1];
    for(int i=1;i<=n;++i) ans=min(ans,dis[i]);
    // for(int i=1;i<=n;++i) printf("%d ",dis[i]); puts("");
    printf("%lld\n",ans);
    return 0;
    
}

贪心的一种写法

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long

int in{
    int i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

const int N=1e3+5;
int n,h[N],ans,now;

signed main(){

    // freopen("1.in","r",stdin);

    n=in;
    for(int i=1;i<=n;++i) h[i]=in;
    sort(h+1,h+n+1);
    int l=1,r=n;
    while(r-l>1){
        ans+=(now-h[r])*(now-h[r]);
        now=h[r];
        ans+=(now-h[l])*(now-h[l]);
        now=h[l];
        --r, ++l;
    }
    if(r-l==0) ans+=(now-h[l])*(now-h[l]);
    if(r-l==1) ans+=(now-h[r])*(now-h[r])+(h[r]-h[l])*(h[r]-h[l]);
    printf("%lld\n",ans);
    return 0;
    
}

贪心的另一种写法

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long

int in{
    int i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

const int N=1e3+5;
int n,h[N],ans,now;

int sqa(int x){return x*x;}

signed main(){

    // freopen("1.in","r",stdin);

    n=in;
    for(int i=1;i<=n;++i) h[i]=in;
    sort(h+1,h+n+1);
    int l=0,r=n;
    for(int i=1;i<=n;++i){
        if(l==r) break;
        ans+=sqa(h[l]-h[r]);
        ++l;
        if(l==r) break;
        ans+=sqa(h[l]-h[r]);
        --r;
    }
    printf("%lld\n",ans);
    return 0;
    
}

标签:nove.12,ch,跳跳,cdots,long,int,while,now
From: https://www.cnblogs.com/antimony-51/p/16882821.html

相关文章

  • 问题 H: 超级跳跳跳1281
    这道题其实本身有点超纲,有点涉及动态规划的内容了,即求最大上升子序列的最大的和写不出来很正常,不用觉得自己菜哈哈哈哈哈,实在不彳亍跳过也是可以的,那我就直接放代码了......
  • 【软件更新】系统激活、硬盘检测、XMind、IDM、万兴PDF、李跳跳、SpeedTest、Ventoy、
    今天照例给大家更新一下之前发过的软件到新版本。大家可以打开每个软件下的链接查看,或者在公众号后台回复相应的关键词获取百度网盘和蓝奏云的下载链接。Windows和Office激......
  • NC227595 跳跳跳
    题目链接题目题目描述dd在玩跳格子游戏,具体游戏规则如下,\(n\)个格子呈环形分布,顺时针方向分别标号为\(1\simn\),其中\(1\)和\(n\)相邻,每个格子上都有一个正整数......