zoukankan      html  css  js  c++  java
  • [hdu6578]Blank

    状态f[i][j][k][l]表示前i个数,四种数的最后一次出现的位置分别是ijkl(i>j>k>l),判断所有第右端点为i的区间是否满足此要求(不满足重置为0),考虑第i+1个位置填什么,转移到下一个位置上即可。

    这样的时间复杂度看似是$o(Tn^{4})$,实际上由于枚举只需要比上一个数小就行了,还要除以24;空间复杂度通过滚动可以压到$o(n^{3})$,可以卡过去。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 998244353
     4 int t,n,m,x,y,z,ans,ll[105][5],rr[105][5],f[2][105][105][105];
     5 void add(int &x,int y){
     6     x+=y;
     7     if (x>=mod)x-=mod;
     8 }
     9 int calc(int a,int b,int c,int d,int e){
    10     return (e<=a)+(e<=b)+(e<=c)+(e<=d);
    11 }
    12 int main(){
    13     scanf("%d",&t);
    14     while (t--){
    15         scanf("%d%d",&n,&m);
    16         memset(ll,0x3f,sizeof(ll));
    17         memset(rr,-1,sizeof(rr));
    18         for(int i=1;i<=m;i++){
    19             scanf("%d%d%d",&x,&y,&z);
    20             ll[y][z]=min(ll[y][z],x);
    21             rr[y][z]=max(rr[y][z],x);
    22         }
    23         memset(f,0,sizeof(f));
    24         f[0][0][0][0]=1;
    25         ans=0;
    26         for(int i=1,p=1;i<=n;i++,p^=1){
    27             for(int j=0;(!j)||(j<i);j++)
    28                 for(int k=0;(!k)||(k<j);k++)
    29                     for(int l=0;(!l)||(l<k);l++){
    30                         x=f[p^1][j][k][l];
    31                         if (x){
    32                             add(f[p][j][k][l],x);
    33                             add(f[p][i-1][k][l],x);
    34                             add(f[p][i-1][j][l],x);
    35                             add(f[p][i-1][j][k],x);
    36                         }
    37                         f[p^1][j][k][l]=0;
    38                     }
    39             for(int j=0;j<i;j++)
    40                 for(int k=0;(!k)||(k<j);k++)
    41                     for(int l=0;(!l)||(l<k);l++){
    42                         for(int q=1;q<=4;q++)
    43                             if ((calc(i,j,k,l,ll[i][q])>q)||(calc(i,j,k,l,rr[i][q])<q)){
    44                                 f[p][j][k][l]=0;
    45                                 break;
    46                             }
    47                         if (i==n)add(ans,f[p][j][k][l]);
    48                     }
    49         }
    50         printf("%d\n",ans);
    51     }
    52 }
    View Code
  • 相关阅读:
    notepad++的使用
    windows下的ubuntu
    VMware Tools安装
    Terminal命令
    Linux文件操作
    vim学习
    Windows桌面美化
    求解移动字符串问题
    求解回文序列问题
    用Git命令把本地项目,提交到远程仓库
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11253923.html
Copyright © 2011-2022 走看看