zoukankan      html  css  js  c++  java
  • 【codevs】3196 黄金宝藏

    【算法】区间DP+博弈论

    【题解】其实它都不是博弈题……

    很自然的可以设f[i][j]表示i~j先手可取得的最大价值。

    容易得到转移式:f[i][j]=max(a[i]+sum[i+1~j]-f[i+1][j],a[j]+sum[i~j-1]-f[i][j-1])。

    化简得到f[i][j]=sum[i~j]-min(f[i+1][j],f[i][j-1])。

    然后预处理前缀和,按区间从小到大做即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=510;
    int a[maxn],f[maxn][maxn],sum[maxn],n;
    int main()
    {
        scanf("%d",&n);
        sum[0]=0;
        for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum[i]=sum[i-1]+a[i];}
        for(int p=0;p<n;p++)
        for(int i=1;i<=n-p;i++)
        f[i][i+p]=sum[i+p]-sum[i-1]-min(f[i+1][i+p],f[i][i+p-1]);
        printf("%d %d",f[1][n],sum[n]-f[1][n]);
        return 0;
    }
    View Code

    因为按区间大小递推所以还可以缩一维空间。

    极大极小搜索是什么,可以吃吗?

  • 相关阅读:
    poj 2262
    poj 1050
    poj 1730
    poj 1061
    【设计模式】简单工厂模式学习
    【待学】
    [设计模式]策略模式和单一职责
    Windows live writer 误删 草稿 恢复
    [Linq]Linq To Sql (2)
    MVC 学习日志1(上)
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7240843.html
Copyright © 2011-2022 走看看