• GarsiaWachs算法


    GarsiaWachs算法

    一个算法,证明网上没找到。
    求石子合并问题的优化。
    step1: 找出第一个 a_k-1 < a_k+1
    step2: 合并a_k-1 + a_k = TmpA
    step3: 将TmpA移动至数组中第一个大于TmpA的数的后面。
    step4: 迭代至数组收敛。
    原题石子合并

    //于石子合并问题,有一个最好的算法,那就是GarsiaWachs算法。时间复杂度为O(n^2)。
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    #define  bg(x)  cout<<(x)<<endl ;
     
    const int N  = 50000 ;
    const int inf =  0x3f3f3f3f;
    int n, a[N], len; // 总长度
    ll ans = 0;
    void dfs(int p)
    {
        if(len==1) return ;
        int k = p, i, j, ret;
        while(k<=len&&a[k-1]>a[k+1]) k++;
        ret = a[k-1] + a[k];
        ans += ret;
        for(i=k;i<=len;i++) a[i] = a[i+1];  //把后面的数字挪过来
        for(j=k-2;j>=0&&a[j]<=ret;j--) a[j+1] = a[j]; // 把前面的数移过去
        a[j+1] = ret;
        len--;
        if(j>=3) j -= 2;   // 对于新插入的数字 也许会导致 之前序列的的“递减”
                            //性质改变,所以要多遍历几个数字
        dfs(j+1);
     
    }
     
    int main(){
        //freopen("test.txt","r",stdin);
        scanf("%d",&n);
        fill(a,a+n+3,inf);
        len = n;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        dfs(1);
        printf("%lld\n",ans );
    }
    
  • 相关阅读:
    无有和无穷
    算法设计 熄灯问题
    WPF 路由事件总结
    C# params关键字
    WPF 布局总结
    C#结构体和类的区别
    C#装箱和拆箱(值类型和引用类型之间的转换)
    OpenGL中平移、旋转、缩放矩阵堆栈操作
    OpenGL图元的颜色属性
    OpenGL基础图形的绘制
  • 原文地址:https://www.cnblogs.com/yesuweiYYYY/p/15523559.html
Copyright © 2020-2023  润新知