zoukankan      html  css  js  c++  java
  • [Luogu2540][NOIP2016]斗地主增强版(搜索+DP)

    增强版就是原版中两鬼不算对子的版本。

    先爆搜出完所有对子,剩下的牌DP处理。

    考虑每个数码的拆牌情况,最多可能被拆成5种情况:1+1+1+1,1+1+2,1+3,2+2,4。故DP状态数最多为5^13≈12e8,事实上远远不满。

    而爆搜部分看上去就跑的挺快,具体复杂度玄学。

    几个降低代码复杂度的方法和注意点:

    1.双王不算对,2不算顺子。

    2.1当14处理,2和双王单独处理。

    3.对于DP状态,先拆牌后打出。

    4.炸弹当三带一打。

    5.DP用记忆化搜索实现,递归边界:既没有3也没有4,这样转移就只需考虑3和4的拆牌和打出了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 using namespace std;
     6 
     7 const int N=30,inf=1e9;
     8 const int lim[4]={0,5,3,2};
     9 int T,n,x,y,a[N],b[N],f[N][N][N][N];
    10 
    11 int calc(int a,int b,int c,int d){
    12     if (a<0 || b<0 || c<0 || d<0) return inf;
    13     if (!c && !d) return a+b;
    14     if (~f[a][b][c][d]) return f[a][b][c][d];
    15     int ans=min(calc(a+1,b,c+1,d-1),calc(a,b+2,c,d-1));//拆四 
    16     ans=min(ans,min(calc(a+3,b,c-1,d),calc(a+1,b+1,c-1,d)));//拆三 
    17     ans=min(ans,min(calc(a-2,b,c,d-1),calc(a,b-1,c,d-1))+1);//四带一 
    18     ans=min(ans,min(calc(a,b-2,c,d-1),calc(a,b,c,d-2))+1);//四带二 
    19     ans=min(ans,min(calc(a-1,b,c-1,d),calc(a,b-1,c-1,d))+1);//三带一 
    20     return f[a][b][c][d]=ans;
    21 }
    22 
    23 int dfs(int x){
    24     int ans=inf;
    25     rep(k,1,3) rep(i,3,14){
    26         int tot=0;
    27         rep(j,i,14) if (a[j]>=k) tot++; else break;
    28         rep(j,i+lim[k]-1,i+tot-1){
    29             rep(l,i,j) a[l]-=k;
    30             ans=min(ans,dfs(x+1));
    31             rep(l,i,j) a[l]+=k;
    32         }
    33     }
    34     b[1]=b[2]=b[3]=b[4]=0;
    35     rep(i,2,14) b[a[i]]++;
    36     if (a[0]==2) ans=min(ans,x+calc(b[1],b[2],b[3],b[4])+1);//火箭 
    37     ans=min(ans,x+calc(b[1]+a[0],b[2],b[3],b[4]));
    38     return ans;
    39 }
    40 
    41 int main(){
    42     freopen("lord.in","r",stdin);
    43     freopen("lord.out","w",stdout);
    44     scanf("%d%d",&T,&n); memset(f,-1,sizeof(f));
    45     while(T--){
    46         memset(a,0,sizeof(a));
    47         rep(i,1,n) scanf("%d%d",&x,&y),a[x]++;
    48         a[14]=a[1]; printf("%d
    ",dfs(0));
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    【一致性检验指标】Kappa(cappa)系数
    仅需4步,轻松升级K3s集群!
    使用Kubernetes、K3s和Traefik2进行本地开发
    超强教程!在树莓派上构建多节点K8S集群!
    使用容器化块存储OpenEBS在K3s中实现持久化存储
    仅需60秒,使用k3sup快速部署高可用K3s集群
    在本地运行Kubernetes的3种主流方式
    为什么Kubernetes在边缘计算中如此关键?
    这4件事,让你了解边缘计算的真实面貌
    极简教程!教你快速将K3s与Cloud Controller集成
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9838595.html
Copyright © 2011-2022 走看看