hdu 6416 dp

Rikka with Seam
Problem Description
Seam carving is a novel algorithm for resizing images while maintaining as much information as possible from the source image.

Now, Rikka is going to use seam carving method to deal with an n×m black and white picture. We can abstract this picture into an n×m 01 matrix A.

A K-seam of this picture is an integer sequence a which satisfies the following conditions:
1. |a|=n, ai∈[1,m].
2. |ai−ai+1|≤K, ∀i∈[1,n).

After choosing a K-seam a, Rikka reduces the size of the picture by deleting pixels (i,ai), and then she gets a matrix A′ of size n×(m−1).

For example, if the chosen seam is [1,2,3] and the picture is
100
111
000

the result matrix will be
00
11
00

Rikka finds that deleting different seams may get the same result. In the previous example, seam [1,2,3],[1,2,1],[1,2,2],[1,1,1] are equivalent.

Now Rikka wants to calculate the number of different matrixes she can get by deleting exactly one K-seam.

Input
The first line contains a single integer t(1≤t≤103), the numebr of testcases.

For each testcase, the first line contains three numbers n,m,K(2≤n,m≤2×103,1≤K≤m).

Then n lines follow, each line contains a 01 string of length m which describes one row of the matrix.

The input guarantees that there are at most 5 testcases with max(n,m)>300.

Output
For each testcase, output a single line with a single number, the answer modulo 998244353.

Sample Input
3
2 2 1
00
10
5 5 1
00100
10101
00100
01000
11101
5 5 2
00100
10101
00100
01000
11101

Sample Output
2
70
199
题意:给出一个n*m的0,1矩阵,每次可以从每一行删掉一个数,每相邻两行删掉的数字的下标的绝对值差值不超过k,问在所有可行的方案下,可以得到多少个不同的矩阵。
做法:首先把,每一行分类,如果在这一行中,删去两个点得到的结果是一样的,那么就认为他们是同一类点,可以发现,相邻的点如果数值相同,那么他们就是一类点,比如说题目中的样例;
100
111
000
就可以分成
122
111
111
对于每一个状态就是它在第一行的类别,第二行的类别,第三行的,如果这3个类别相同,那么就可以认为他们得到的结果是一样的,
然后就可以dp了,首先开两个dp数组,对于d[i][j],p[i][j];p[i][j]代表到第i行的时候,最后一个选择是j的不同的方案数目,d[i][j]代表(i,j)这个点拥有的,但是(i,j-1)这个点所没有的状态数,
然后更新的时候,可知点到达(i,j)的所有状态就是它上一层(i-1,j-k)到(i-1,j+k)这个区间的所有不同的状态,当然这里面有很多重复的状态,那么有一个想法,
在(i,j)这个状态加上(i-1,j-k)里面所有的状态,然后加上(i-1,j-k-1)有的状态,但是(i-1,j-k)没有的状态,再加上(i-1,j-k+2)有的但是(i-1,j-k+1),(i-1,j-k)没有的状态就好了,实现的话:还记得前面那个d[i][j]吧,保存一个点有的但是它前一个点没有的状态,所以对于(i,j)这个点,它的方案数就是p[i-1][j-k]+sum(d[i-1][j-k+1],d[i-1][j-k+2],,,,dp[i-1][j+k]),至于为什么呢,两个点有相同的状态的前提是他们在同一行的同一类里面。通过观察可以发现对于同一行的三个点x,y,z,x

#include<bits/stdc++.h>
using namespace std;
const int N = 2005;
int d[N][N],p[N][N];
char st[N][N];
const int mod = 998244353;
void add(int &x,int y){
    /*x += y;
    if(x >= mod) x -= mod;
    if(x < 0) x += mod;*/
    x += y;

    x %= mod;
    x += mod;
    x %= mod;
}

int main(){
    int T;
    cin >> T;
    while(T--){
        int n,m,k;
        scanf("%d %d %d",&n,&m,&k);
        /*memset(d,0,sizeof(d));
        memset(p,0,sizeof(p));*/
        for(int i = 0;i <= n;i ++){
            for(int j = 0;j <= m;j ++) d[i][j] = p[i][j] = 0;
        }
        for(int i = 1;i <= n;i ++){
            scanf("%s",st[i]+1);
        }
        for(int i = 1;i <= m;i ++){
            if(st[1][i] != st[1][i-1]) d[1][i] = 1;
            p[1][i] = 1;
        }
        for(int i = 1;i <= n-1;i ++){
            for(int j= 1;j <= m;j ++){
                int nl= max(1,j-k);
                int nr = min(m+1,j+k);
                //cout <<i<< ' ' <<j << ' '<<nl << ' '<< nr <<' '<<d[i][j] << ' '<<p[i][j] <<  endl;
                add(p[i+1][nl],d[i][j]);
                add(p[i+1][nr],-d[i][j]);
                if(j+k<=m){
                    add(p[i+1][nr],p[i][j]);
                    add(p[i+1][nr+1],-p[i][j]);
                }
            }
            for(int j = 1;j <= m;j ++){
                add(p[i+1][j],p[i+1][j-1]);
                if(st[i+1][j] != st[i+1][j-1]) d[i+1][j] = p[i+1][j];
                else if(j+k<= m) d[i+1][j] = d[i][j+k];
            }
        }
        /*for(int i = 1;i <= n;i ++){
            for(int j= 1;j <= m;j ++){
                    cout << i<< ' '<<j << ' '<< d[i][j] << ' ' << p[i][j] << endl;
            }
        }*/
        int ans=  0;
        for(int i= 1;i <= m;i ++) add(ans,d[n][i]);
        printf("%d\n",ans);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/81907750