• 2018多校第九场 HDU 6416 (DP+前缀和优化)


    转自:https://blog.csdn.net/CatDsy/article/details/81876341

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define mst(a,b) memset((a),(b),sizeof(a))
    #define pi acos(-1)
    #define pii pair<int,int>
    const int INF = 0x3f3f3f3f;
    const double eps = 1e-6;
    const int MAXN = 2e3 + 10;
    const int MAXM = 2e6 + 10;
    const ll mod = 998244353;
    
    char s[MAXN][MAXN];
    ll tot[MAXN][MAXN], same[MAXN][MAXN];
    ll pre_tot[MAXN][MAXN], pre_same[MAXN][MAXN];
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d",&t);
        while(t--) {
            int n,m,k;
            scanf("%d%d%d",&n,&m,&k);
            for(int i = 1; i <= n; i++)
                scanf("%s",s[i] + 1);
            for(int i = 1; i <= n; i++)
                pre_tot[i][0] = pre_same[i][0] = 0;
            for(int i = 1; i <= m; i++) {
                tot[1][i] = 1;
                pre_tot[1][i] = i;
                if(i == 1 || s[1][i] != s[1][i - 1]) same[1][i] = 0;
                else same[1][i] = 1;
                pre_same[1][i] = pre_same[1][i - 1] + same[1][i];
            }
            for(int i = 2; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    int l = max(j - k, 1), r = min(j + k, m);
                    tot[i][j] = (pre_tot[i - 1][r] - pre_tot[i - 1][l - 1] + mod) % mod;
                    l = max(j - k + 1, 1), r = min(j + k, m);
                    tot[i][j] = (tot[i][j] - (pre_same[i - 1][r] - pre_same[i - 1][l - 1] + mod) % mod + mod) % mod;
                    pre_tot[i][j] = (pre_tot[i][j - 1] + tot[i][j]) % mod;
                    if(j == 1 || s[i][j] != s[i][j - 1]) same[i][j] = 0;
                    else {
                        l = max(j - k, 1), r = min(j + k - 1, m);
                        same[i][j] = (pre_tot[i - 1][r] - pre_tot[i - 1][l - 1] + mod) % mod;
                        l = max(j - k + 1, 1), r = min(j + k - 1, m);
                        same[i][j] = (same[i][j] - (pre_same[i - 1][r] - pre_same[i - 1][l - 1] + mod) % mod + mod) % mod;
                    }
                    pre_same[i][j] = (pre_same[i][j - 1] + same[i][j]) % mod;
                }
            }
            ll ans = 0;
            for(int i = 1; i <= m; i++)
                ans = (ans + tot[n][i] - same[n][i] + mod) % mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }

    题目描述:

    给定一个NMN∗M的01矩阵

    K-seam是满足以下条件的整数序列a:

    • |a|=n,ai[1,m]|a|=n,ai∈[1,m]
    • |aiai+1|K,i[1,n)|ai−ai+1|≤K,i∈[1,n)

    对于第ii行,删除第aiai个数,会得到一个N(M1)N∗(M−1)的矩阵

    不同的整数序列可能会得到相同的矩阵

    问:可以得到多少种不同的矩阵


    题解:

    如果无视different的条件 
    定义状态:dp[i][j]dp[i][j]——删除第 ii 行第 jj 个数可以得到的矩阵总数 
    可推得转移方程如下:

     
    dp[i][j]=x=jkj+kdp[i1][x]dp[i][j]=∑x=j−kj+kdp[i−1][x]

     

    在此基础上,加上different的条件 
    定义状态:

    • tot[i][j]tot[i][j]——删除第 ii 行第 jj 个数可以得到的不同的矩阵总数
    • same[i][j]same[i][j]——删除第 ii 行第 jj 个数和删除第 ii 行第 j1j−1 个数后得到的相同方案数

    那么,tot[i][j]tot[i][j]的状态转移方程为: 

     
    tot[i][j]=x=jkj+ktot[i1][x]x=jk+1j+ksame[i1][x]tot[i][j]=∑x=j−kj+ktot[i−1][x]−∑x=j−k+1j+ksame[i−1][x]


    如果 Matrix[i][j]Matrix[i][j1]Matrix[i][j]≠Matrix[i][j−1] 那么,same[i][j]=0same[i][j]=0 
    否则,对于第 jj 个和第 j1j−1 个的转移区间分别为[jk,j+k][j−k,j+k][j1k,j1+k][j−1−k,j−1+k],那么它们的交叉区间为[jk,j1+k][j−k,j−1+k],即:从该区间内转移得到的方案数会重复计算一次。得到 same[i][j]same[i][j] 的转移方程为: 

     
    same[i][j]=x=jkj+k1tot[i1][x]x=jk+1j+k1same[i1][x]same[i][j]=∑x=j−kj+k−1tot[i−1][x]−∑x=j−k+1j+k−1same[i−1][x]

     

    时间复杂度为O(nm2)O(n∗m2),对于做前缀和优化,时间复杂度降为O(nm)O(n∗m)

    最后,对于第n行计算总的不同的方案数,即ans=totsame

  • 相关阅读:
    vmware图形化安装kali iso镜像文件启动后黑屏问题解决方法
    8818驱动蓝屏报错解决方法
    v3ray提示已经在运行的错误
    逆向工程之安卓逆向- --- p命名法中插入一个新寄存器
    硬件黑客之无线电 --- Proxmark3 RDV4 套件
    硬件黑客之无线电 --- Plunder Bug LAN Tap
    硬件黑客之局域网安全 --- 鲨鱼杰克
    硬件黑客之无线电 --- Proxmark3 RDV4 套件
    硬件黑客之无线电 --- NFC Kill
    硬件黑客之无线电 --- 双频 WiFi RTL8812AU
  • 原文地址:https://www.cnblogs.com/scaulok/p/9580628.html
Copyright © 2020-2023  润新知