Codeforces268D. Wall Bars 五维dp

2023-11-30 13:20

本文主要是介绍Codeforces268D. Wall Bars 五维dp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:D. Wall Bars

time limit per test

4 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Manao is working for a construction company. Recently, an order came to build wall bars in a children's park. Manao was commissioned to develop a plan of construction, which will enable the company to save the most money.

After reviewing the formal specifications for the wall bars, Manao discovered a number of controversial requirements and decided to treat them to the company's advantage. His resulting design can be described as follows:

  • Let's introduce some unit of length. The construction center is a pole of height n.
  • At heights 1, 2, ..., n exactly one horizontal bar sticks out from the pole. Each bar sticks in one of four pre-fixed directions.
  • A child can move from one bar to another if the distance between them does not exceed h and they stick in the same direction. If a child is on the ground, he can climb onto any of the bars at height between 1 and h. In Manao's construction a child should be able to reach at least one of the bars at heights n - h + 1, n - h + 2, ..., n if he begins at the ground.

The figure to the left shows what a common set of wall bars looks like. The figure to the right shows Manao's construction

Manao is wondering how many distinct construction designs that satisfy his requirements exist. As this number can be rather large, print the remainder after dividing it by 1000000009 (109 + 9). Two designs are considered distinct if there is such height i, that the bars on the height i in these designs don't stick out in the same direction.

Input

A single line contains two space-separated integers, n and h (1 ≤ n ≤ 1000, 1 ≤ h ≤ min(n, 30)).

Output

In a single line print the remainder after dividing the number of designs by 1000000009 (109 + 9).

Examples

input

Copy

5 1

output

Copy

4

input

Copy

4 2

output

Copy

148

input

Copy

4 3

output

Copy

256

input

Copy

5 2

output

Copy

376

Note

Consider several designs for h = 2. A design with the first bar sticked out in direction d1, the second — in direction d2 and so on (1 ≤ di ≤ 4) is denoted as string d1d2...dn.

Design "1231" (the first three bars are sticked out in different directions, the last one — in the same as first). A child can reach neither the bar at height 3 nor the bar at height 4.

Design "414141". A child can reach the bar at height 5. To do this, he should first climb at the first bar, then at the third and then at the fifth one. He can also reach bar at height 6 by the route second  →  fourth  →  sixth bars.

Design "123333". The child can't reach the upper two bars.

Design "323323". The bar at height 6 can be reached by the following route: first  →  third  →  fourth  →  sixth bars.

题意有一个长度为n的杆子从1~n的每个节点可以伸出一个杆子来这个杆子可以指向东南西北四个方向中的任意一个方向。有一个猴他每次跳跃的高度最大为h,他在地面上时可以跳向高度小于h的任意一个杆(不论方向),但是他跳到杆子上之后就只能延当前方向跳,结束的条件就是他能跳到n-h+1~n这些高度中的任意一个,假设你是一个设计师问你一共有多少种设计方案能使这只猴达成目标。

dp[i][a][b][c][d];表示建造到第i层,a表示所选的主要面(猴子爬的那一面)是否可达1表示可达,0不可达然后bcd分别表示另外三个面到当前阶层的距离,如果说相差大于h那么就和h没有差别了都是跳不上去那么就把另外3维降成了30要不五维数组开都开不了。

一开始我比较困惑如何将这一层的主要面转换成下一层的次要面,因为只有主要面是0,1次要面是0~h然后明白如果说他能到达那么那么第i层距离第i+1层肯定就是1否则就说明i层之前肯定有断层即无法继续往上爬所以直接就令他等于h即可。

#include<bits/stdc++.h>
using namespace std;
const long long inf=1000000009;
long long dp[1001][2][31][31][31];
int main(){int n,h;cin>>n>>h;memset(dp,0,sizeof(dp));dp[0][1][0][0][0]=1;for(int i=0;i<n;i++){for(int a=0;a<2;a++){for(int b=0;b<=h;b++){for(int c=0;c<=h;c++){for(int d=0;d<=h;d++){dp[i+1][a][min(b+1,h)][min(c+1,h)][min(d+1,h)]=(dp[i+1][a][min(b+1,h)][min(c+1,h)][min(d+1,h)]+dp[i][a][b][c][d])%inf;dp[i+1][b+1<=h?1:0][a?1:h][min(c+1,h)][min(d+1,h)]=(dp[i+1][b+1<=h?1:0][a?1:h][min(c+1,h)][min(d+1,h)]+dp[i][a][b][c][d])%inf;dp[i+1][c+1<=h?1:0][min(b+1,h)][a?1:h][min(d+1,h)]=(dp[i+1][c+1<=h?1:0][min(b+1,h)][a?1:h][min(d+1,h)]+dp[i][a][b][c][d])%inf;dp[i+1][d+1<=h?1:0][min(b+1,h)][min(c+1,h)][a?1:h]=(dp[i+1][d+1<=h?1:0][min(b+1,h)][min(c+1,h)][a?1:h]+dp[i][a][b][c][d])%inf;}}}}}long long ans=0;for(int i=0;i<2;i++){for(int j=0;j<=h;j++){for(int k=0;k<=h;k++){for(int l=0;l<=h;l++){if(i==1||j<h||k<h||l<h){ans+=dp[n][i][j][k][l];if(ans>inf)ans-=inf;}}}}}cout<<ans<<endl;}

 

这篇关于Codeforces268D. Wall Bars 五维dp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437184

相关文章

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。 思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] )  代码如下: #include <stdio.h>#include

usaco 1.1 Broken Necklace(DP)

直接上代码 接触的第一道dp ps.大概的思路就是 先从左往右用一个数组在每个点记下蓝或黑的个数 再从右到左算一遍 最后取出最大的即可 核心语句在于: 如果 str[i] = 'r'  ,   rl[i]=rl[i-1]+1, bl[i]=0 如果 str[i] = 'b' ,  bl[i]=bl[i-1]+1, rl[i]=0 如果 str[i] = 'w',  bl[i]=b

uva 10154 DP 叠乌龟

题意: 给你几只乌龟,每只乌龟有自身的重量和力量。 每只乌龟的力量可以承受自身体重和在其上的几只乌龟的体重和内。 问最多能叠放几只乌龟。 解析: 先将乌龟按力量从小到大排列。 然后dp的时候从前往后叠,状态转移方程: dp[i][j] = dp[i - 1][j];if (dp[i - 1][j - 1] != inf && dp[i - 1][j - 1] <= t[i]

uva 10118 dP

题意: 给4列篮子,每次从某一列开始无放回拿蜡烛放入篮子里,并且篮子最多只能放5支蜡烛,数字代表蜡烛的颜色。 当拿出当前颜色的蜡烛在篮子里存在时,猪脚可以把蜡烛带回家。 问最多拿多少只蜡烛。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cs

uva 10069 DP + 大数加法

代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <cl

uva 10029 HASH + DP

题意: 给一个字典,里面有好多单词。单词可以由增加、删除、变换,变成另一个单词,问能变换的最长单词长度。 解析: HASH+dp 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int