• hdu1693-Eat the Trees


    题目

    一个方格图,有一些点是障碍,求有用一些回路精确覆盖非障碍点的方案数。(n,mle 11)

    分析

    开始学插头dp,这是第一题。

    这其实可以说是一个轮廓线dp,因为可以用多个回路,所以无须保存其他的连通性状态,只要记录从上到下,从左到右dp到每一个点的时候每一种插头情况的方案数,一个个转移即可。画一下图就知道了。

    最开始纠结的是初始化问题。其实为了代码方便,可以初始化 f[0][m][0]=1,这样在处理换行的时候就会自动把这个顺延到第一行。换行处理就左移一下,因为前一行的最后一个(右插头)和当前行的第一个(右插头)必定是空的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long giant;
    inline giant read() {
    	giant x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const giant maxn=12;
    const giant maxs=1<<maxn;
    giant f[maxn][maxn][maxs];
    bool a[maxn][maxn];
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	giant T=read(),cas=0;
    	while (T--) {
    		memset(f,0,sizeof f);
    		giant n=read(),m=read(),s=1<<(m+1);
    		for (giant i=1;i<=n;++i) for (giant j=1;j<=m;++j) a[i][j]=read();
    		f[0][m][0]=1;
    		for (giant i=1;i<=n;++i) {
    			for (giant k=0;k<(1<<m);++k) f[i][0][k<<1]=f[i-1][m][k];
    			for (giant j=1;j<=m;++j) {
    				for (giant k=0;k<s;++k) {
    					bool lef=((k>>(j-1))&1),up=((k>>j)&1);
    					giant x=(1<<(j-1))|(1<<j);
    					if (!a[i][j]) {
    						if (!lef && !up) f[i][j][k]+=f[i][j-1][k];
    					} else if (lef^up) f[i][j][k]+=f[i][j-1][k],f[i][j][k^x]+=f[i][j-1][k]; else f[i][j][k^x]+=f[i][j-1][k];
    				}
    			}
    		}
    		printf("Case %lld: There are %lld ways to eat the trees.
    ",++cas,f[n][m][0]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    HTML 5 视频/音频
    vue 未完待续
    asp.net中使用log4net
    图片预加载:jquery 图片预加载功能,可以实现先模糊在清晰的显示
    IIS配置PHP环境
    学习ASP.Net的过滤器
    最好用的jQuery插件,240多个,绝对的JQUERY插件库
    Windows7&IIS7.5部署Discuz全攻略
    AjaxPro使用
    ASP.NET XML读取、增加、修改和删除操作
  • 原文地址:https://www.cnblogs.com/owenyu/p/7279468.html
Copyright © 2020-2023  润新知