• 「USACO06NOV」玉米田 Corn Fields


    「USACO06NOV」玉米田 Corn Fields

    解题思路

    这题是一道经典的状压(DP)
    (f_{i,j}) 表示当前处理到第 (i) 行,这行的状态为 (j)

    转移更简单

    [f_{i,j} = sum _ {k = 1} ^ {k <= w} f _ {i - 1,k} ]

    (w)(i - 1) 行的状态数量
    转移时要排除不可能的情况

    对于状态,我们可以用 预处理出每一行有可能的状态

    时间复杂度为(O(2 ^ {2m} n)),不会跑满

    Code

    #include<cstdio>
    using namespace std;
    const int P = 1e8;
    long long f[14][4400];
    int sta[14][4400],n,m,a[14][14];
    
    void dfs(int u,int x,int s)\预处理状态
    {
    	if (x > m)
    	{
    		sta[u][++sta[u][0]] = s;
    		return;
    	}
    	dfs(u,x + 1,s);
    	if (a[u][x]) dfs(u,x + 2,s | (1 << x - 1));
    }
    int main()
    {
    	freopen("cowfood.in","r",stdin);
    	freopen("cowfood.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= m; j++)
    			scanf("%d",&a[i][j]);
    	for (int i = 1; i <= n; i++)
    		dfs(i,1,0);
    	for (int i = 1; i <= sta[1][0]; i++) f[1][i] = 1;
    	for (int i = 2; i <= n; i++)
    		for (int j = 1; j <= sta[i][0]; j++)
    			for (int k = 1; k <= sta[i - 1][0]; k++)
    			{
    				if (sta[i][j] & sta[i - 1][k]) continue;\排除不可能的情况
    				f[i][j] = (f[i][j] + f[i - 1][k]) % P;
    			}
    	long long ans = 0;
    	for (int i = 1; i <= sta[n][0]; i++) ans = (ans + f[n][i]) % P;
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    云计算
    uc/xi
    互联网 2.0概念
    java连接数据库
    记录一下安装 mysql 的踩坑之路
    1
    Linux介绍与基本必知命令
    Web课程Linux命令统计
    7——条件判断、三目运算、条件循环、迭代循环
    6——散列类型、运算符优先级、逻辑运算
  • 原文地址:https://www.cnblogs.com/nibabadeboke/p/13465982.html
Copyright © 2020-2023  润新知