Caesar's Legions(dp)

Caesar‘s Legions

Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

Gaius Julius Caesar, a famous general, loved to line up his soldiers. Overall the army had n1 footmen and n2 horsemen. Caesar thought that an arrangement is not beautiful if somewhere in the line there are strictly more that k1 footmen standing successively one after another, or there are strictly more than k2 horsemen standing successively one after another. Find the number of beautiful arrangements of the soldiers.

Note that all n1 + n2 warriors should be present at each arrangement. All footmen are considered indistinguishable among themselves. Similarly, all horsemen are considered indistinguishable among themselves.

Input

The only line contains four space-separated integers n1n2k1k2 (1 ≤ n1, n2 ≤ 100, 1 ≤ k1, k2 ≤ 10) which represent how many footmen and horsemen there are and the largest acceptable number of footmen and horsemen standing in succession, correspondingly.

Output

Print the number of beautiful arrangements of the army modulo 100000000(108). That is, print the number of such ways to line up the soldiers, that no more than k1 footmen stand successively, and no more than k2 horsemen stand successively.

Sample Input

Input

2 1 1 10

Output

1

Input

2 3 1 2

Output

5

Input

2 4 1 1

Output

0

Hint

Let‘s mark a footman as 1, and a horseman as 2.

In the first sample the only beautiful line-up is: 121

In the second sample 5 beautiful line-ups exist: 12122, 12212, 21212, 21221, 22121

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 long long ans;
 6 long long dp1[110][110][12];
 7 long long dp2[110][110][12];
 8 int main()
 9 {
10     int n1,n2,k1,k2,i,j,k;
11     while(scanf("%d%d%d%d",&n1,&n2,&k1,&k2)!=EOF){
12         memset(dp1,0,sizeof(dp1));
13         memset(dp2,0,sizeof(dp2));
14         dp1[1][0][1]=1; dp2[0][1][1]=1;
15         for(i=0;i<=n1;i++){
16             for(j=0;j<=n2;j++){
17                 for(k=1;k<=k1;k++){
18                     if(dp1[i][j][k]){
19                         if(k!=k1){
20                             dp1[i+1][j][k+1]+=dp1[i][j][k];
21                             dp1[i+1][j][k+1]%=100000000;
22                         }
23                         dp2[i][j+1][1]+=dp1[i][j][k];
24                         dp2[i][j+1][1]%=100000000;
25                     }
26                 }
27                 for(k=1;k<=k2;k++){
28                     if(dp2[i][j][k]){
29                         if(k!=k2){
30                             dp2[i][j+1][k+1]+=dp2[i][j][k];
31                             dp2[i][j+1][k+1]%=100000000;
32                         }
33                         dp1[i+1][j][1]+=dp2[i][j][k];
34                         dp1[i+1][j][1]%=100000000;
35                     }
36                 }
37             }
38         }
39         ans=0;
40         for(i=1;i<=k1;i++){
41             ans+=dp1[n1][n2][i];
42             ans%=100000000;
43         }
44         for(i=1;i<=k2;i++){
45             ans+=dp2[n1][n2][i];
46             ans%=100000000;
47         }
48         printf("%I64d\n",ans);
49     }
50     return 0;
51 }

Caesar's Legions(dp)

时间: 2025-01-14 03:03:08

Caesar's Legions(dp)的相关文章

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

Codeforces118D Caesar&#39;s Legions(DP)

题目 Source http://codeforces.com/problemset/problem/118/D Description Gaius Julius Caesar, a famous general, loved to line up his soldiers. Overall the army had n1 footmen and n2 horsemen. Caesar thought that an arrangement is not beautiful if somewhe

codeforces118D - Caesar&#39;s Legions 多维DP

题意:给你n1个人,n2匹马站成一排,最多k1个人连续站,最多k2匹马连续站,问你有多少种方法 解题思路:4维dp,i,j,s,k分别代表位置,已经站了多少人,前一个站的是人还是马,一共连续站了几位了. 解题代码: 1 // File Name: 118d.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月25日 星期五 15时35分03秒 4 5 #include<vector> 6 #include<list> 7 #i

Codeforces-118D. Caesar&#39;s Legions(lazy dynamics)

传送门 把n1个步兵和n2个骑兵派成一列,已知连续的步兵不超过k1个,连续的骑兵不超过k2个,求总可能排列情况数 定义dp[i][j][2],指使用i个步兵,j个骑兵的排列.0代表排头为步兵,1代表排头为骑兵 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 0x3f3f3f3f #define MOD 100000000 usi

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是