zoukankan      html  css  js  c++  java
  • CF268D Wall Bars

    Solution

    给我的感觉就是很暴力的计数DP。

    因为再暴力,这也算个DP

    那么我们可以显然的构造出一个状态 (f_{i,a,b,c,1/0}) ,表示现在是第 (i) 个踏板放在某个面上,其它三个面的下一个踏板距离这个的距离为 (a,b,c) ,当前这个踏板是/否能从地面到达。

    在此我们是优化了一维,也就是将 (i) 踏板所在面下一个距离这个踏板的距离优化成了 (1/0) ,因为能到达的时候距离是 (<h) 的,不能时是 (geq h) 的,也是两个状态。

    再思考另一个问题,开了五维数组,那么空间复杂度是 (O(n imes n imes n imes n imes 2)=O(n^4)) ,显然是会炸的。我们还得优化空间,发现题目中说明 (hleq min(n,30)) ,所以可以将 (a,b,c) 三维的空间变成30,当距离 (geq h) 时,赋为 (h) 。此时为 (O(2cdot 30^3cdot n)) ,完全可以。

    再看时间复杂度。发现我们在优化空间的时候,把时间复杂度也降低了。本来要枚举五维,复杂度是 (O(n^5)) ,现在也变成了 (O(2cdot 30^3cdot n))

    现在终于到了最重要的转移方程:

    [f_{i+1,a+1,b+1,c+1,1/0}+=f_{i,a,b,c,1/0} ]

    这个是还在本来的那个面上

    [f_{i+1,1/h,b+1,c+1,[a<h]}+=f_{i,a,b,c,1/0} ]

    这是换到另一个面

    [f_{i+1,a+1,1/h,c+1,[b<h]}+=f_{i,a,b,c,1/0}, f_{i+1,a+1,b+1,1/h,[c<h]}+=f_{i,a,b,c,1/0} ]

    这两个同理。

    答案随便求求即可。

    代码

    #include<bits/stdc++.h>
    #define ll long long
    
    using namespace std;
    const int mod=1e9+9;
    int n,h,ans;
    int f[1010][31][31][31][2];
    
    #define add(i,a,b,c,j,val) (f[i][min(a,h)][min(b,h)][min(c,h)][j]+=val)%=mod;
    ll read(){
    	int x=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    	return x*f;
    }
    
    int main(){
    	n=read();h=read();
    	f[1][1][1][1][1]=4;
    	for(int i=1;i<=n;i++)
    		for(int a=1;a<=h;a++)
    			for(int b=1;b<=h;b++)
    				for(int c=1;c<=h;c++)
    					for(int j=0;j<2;j++)
    						if(f[i][a][b][c][j]){
    							add(i+1,a+1,b+1,c+1,j,f[i][a][b][c][j]);
    							int d=1;if(j==0) d=h;
    							add(i+1,d,b+1,c+1,a<h,f[i][a][b][c][j]);
    							add(i+1,a+1,d,c+1,b<h,f[i][a][b][c][j]);
    							add(i+1,a+1,b+1,d,c<h,f[i][a][b][c][j]);
    						}
    	for(int a=1;a<=h;a++)
    		for(int b=1;b<=h;b++)
    			for(int c=1;c<=h;c++)
    				for(int j=0;j<2;j++)
    					if(j||a<h||b<h||c<h) ans=(ans+f[n][a][b][c][j])%mod;
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    升讯威微信营销系统开发实践:目录
    升讯威微信营销系统开发实践:订阅号和服务号深入分析( 完整开源于 Github)
    ASP.NET MVC (Razor)开发<<周报与绩效考核系统>>,并免费提供园友们使用~~~
    使用 SailingEase WinForm 框架构建复合式应用程序(插件式应用程序)
    vertica提取json字段值
    centos上配置redis从节点
    查看出网IP
    centos上tcp抓包
    修改centos服务器时区并同步最新时间
    解决centos下tomcat启动太慢 & JDBC连接oracle太慢的问题
  • 原文地址:https://www.cnblogs.com/jasony/p/13927899.html
Copyright © 2011-2022 走看看