zoukankan      html  css  js  c++  java
  • [CF293B] Distinct Paths

    问题描述

    给定一个 n*m 的矩形色板,有 k 种不同的颜料,有些格子已经填上了某种颜色,现在 需要将其他格子也填上颜色,使得从左上角到右下角的任意路径经过的格子都不会出现两种 及以上相同的颜色。路径只能沿着相邻的格子,且只能向下或者向右。 计算所有可能的方案,结果对 1000000007 (10^9 + 7)求模。

    输入格式

    第一行,三个整数 n, m, k (1 ≤ n, m ≤ 1000, 1 ≤ k ≤ 10); 接下来 n 行,每行包含 m 个整数,表示颜色。其中 0 表示未涂色,非 0 表示颜色的编号, 颜色编号为 1 到 k。

    输出格式

    一行,一个整数,表示涂色方案对 1000000007 (10^9 + 7)求模的结果。

    样例输入

    2 2 4
    0 0
    0 0

    样例输出

    48

    解析

    首先,从(1,1)到(n,m)的路径长度为n+m-1,那么如果颜色种类数小于n+m-1,无论如何都不存在解。所以,我们把n和m的范围缩小到了10。

    观察条件:从左上角到右下角的任意路径经过的格子都不会出现两种及以上相同的颜色。既然是任意路径,那么不难得到推论,一个格子的左上方不能出现和自己相同的颜色。而颜色种类只有10,不妨用状压的方法储存一个点左上角出现过的颜色集合。具体的,设(f[i][j])表示(i , j)左上角出现过的颜色集合,则

    [f[i][j]=f[i-1][j] | f[i][j-1] ]

    还有一个剪枝。如果在某个格子上,某种颜色是第一次出现,那么这个格子上其他第一次出现的颜色得到的方案数和这个颜色是相同的,不必重复计算。

    代码

    #include <iostream>
    #include <cstdio>
    #define N 1002
    using namespace std;
    const int mod=1000000007;
    int n,m,k,i,j,a[N][N],vis[12],col[N][N];
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    int count(int x)
    {
    	int ans=0;
    	for(int i=0;(1<<i)<=x;i++){
    		if(x&(1<<i)) ans++;
    	}
    	return ans;
    }
    int dfs(int x,int y)
    {
    	if(y==m+1) x++,y=1;
    	if(x==n+1) return 1;
    	int s=(col[x-1][y]|col[x][y-1])^((1<<k)-1),ans=0,tmp=-1;
    	if(n-x+m-y+1>count(s)) return 0;
    	for(int i=0;(1<<i)<=s;i++){
    		if(s&(1<<i)&&(a[x][y]==0||a[x][y]==i+1)){
    			col[x][y]=(col[x][y-1]|col[x-1][y]|(1<<i));
    			vis[i+1]++;
    			if(vis[i+1]==1){
    				if(tmp==-1) tmp=dfs(x,y+1);
    				ans=(ans+tmp)%mod;
    			}
    			else ans=(ans+dfs(x,y+1))%mod;
    			vis[i+1]--;
    		}
    	}
    	return ans;
    }
    int main()
    {
    	n=read();m=read();k=read();
    	for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			a[i][j]=read();
    			vis[a[i][j]]++;
    		}
    	}
    	if(n+m-1>k) puts("0");
    	else printf("%d
    ",dfs(1,1));
    	return 0;
    }
    
  • 相关阅读:
    论人力资源的危机及其对策(3)
    maven常见问题问答
    bigtall的敏捷日记(1)
    项目管理沙龙的第一次聚会纪要
    论人力资源的危机与对策(2)
    Crest的OO核心实现
    阿里巴巴图标库,助力微信小程序开发
    微信小程序漂亮的搜索框【样式】
    C# windows 服务看门狗
    微信小程序生命周期
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11789897.html
Copyright © 2011-2022 走看看