zoukankan      html  css  js  c++  java
  • 【九省联考2018】一双木棋

    题面

    https://www.luogu.org/problem/P4363

    题解

    很套路的$hash$状态$+dp$。

    可知棋子形成的形状一定是一个连续的倒楼梯形(楼梯向右延伸的长度可以不连续,但一定单调)

    $hash$轮廓就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define ri register int
    #define N 11
    #define LL long long
    #define INF 1000000007
    #define mod 1233107
    using namespace std;
    int a[N][N],b[N][N];
    LL pow[N];
    int n,m;
    vector<int>f[mod];
    vector<LL>g[mod];
    
    int dfs(LL x) {
      int ln[N];
      int yx=x%mod;
      for (ri i=0;i<g[yx].size();i++) if (g[yx][i]==x) return f[yx][i];
      g[yx].push_back(x);
      f[yx].push_back(0);
      int tl=f[yx].size()-1;
      int tot=0,opt,ret;
      LL tx=x,nx;
      for (ri i=n;i>=1;i--) {
        ln[i]=x/pow[i];
        x%=pow[i];
      }
      ln[0]=m+1;
      for (ri i=1;i<=n;i++) tot+=ln[i];
      if (tot==n*m) return 0;
      if (tot%2==0) opt=1; else opt=0;
        
      if (opt) ret=-INF; else ret=INF;
      for (ri i=1;i<=n;i++) if (ln[i-1]>ln[i] && ln[i]+1<=m) {
        nx=tx+pow[i];
        if (opt) {
          int t=dfs(nx);
          if (a[i][ln[i]+1]+t>ret) ret=a[i][ln[i]+1]+t;
        }
        else {
          int t=dfs(nx);
          if (-b[i][ln[i]+1]+t<ret) ret=-b[i][ln[i]+1]+t;
        }
      }
      return f[yx][tl]=ret;
    }
    
    int main(){
      cin>>n>>m;
      for (ri i=1;i<=n;i++) 
        for (ri j=1;j<=m;j++) cin>>a[i][j];
      for (ri i=1;i<=n;i++)
        for (ri j=1;j<=m;j++) cin>>b[i][j];
      pow[1]=1LL;
      for (ri i=2;i<=n;i++) pow[i]=pow[i-1]*11LL;
      printf("%d
    ",dfs(0));
    }
  • 相关阅读:
    mosquitto配置文件说明
    Mac 下 Mosquitto 安装和配置 (Mosquitto为开源的mqtt服务器)
    transfer learning
    NP问题
    旋转矩阵与四元数
    在数学中一个非凸的最优化问题是什么意思?
    国产操作系统优麒麟安装步骤
    齐次坐标
    反走样
    数据分析师
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11426246.html
Copyright © 2011-2022 走看看