HDU 4832 Chess

同样是百度之星的题目。
刚开始看题目,觉得这是一道搜索的题,于是就萌生了找题解的想法。一开始就没有斗志,当然不会做出这道题的啦。

可是看完题解恍然大悟,原来是DP,而且很简单的一道DP。
再一次失败,说明了看题解真的不是一个好习惯。我要改! 我要改!!

其实基本的思想就是把这个二维移动分开,变成一维的移动,最后加上组合数就OK了。

下面的是代码,虽然是自己敲的,但是还是剽窃过来的。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod = 9999991;
const int maxn = 1010;
#define LL long long

LL sum[2][maxn], dp[2][maxn][maxn];
LL C[1010][1010];

void init()
{
    memset(sum, 0, sizeof(sum));
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < maxn; i++)
        C[i][i] = 1, C[i][0] = 1;
    for(int i = 2; i < maxn; i++)
        for(int j = 1; j < i; j++)
            C[i][j] =(C[i-1][j] + C[i-1][j-1]) % mod;
}

void solve(int n, int k, int t, int p)
{
    dp[p][0][t] = 1;
    sum[p][0] = 1;
    for(int i = 1; i <= k; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if(j - 1 > 0)  dp[p][i][j] += dp[p][i-1][j-1];
            if(j - 2 > 0)  dp[p][i][j] += dp[p][i-1][j-2];
            if(j + 1 <= n) dp[p][i][j] += dp[p][i-1][j+1];
            if(j + 2 <= n) dp[p][i][j] += dp[p][i-1][j+2];
            dp[p][i][j] %= mod;
            sum[p][i] = (sum[p][i] + dp[p][i][j]) % mod;
        }
    }
    return ;
}

LL getans(int k)
{
    LL ans = 0;
    for(int i = 0; i <= k; i++)
        ans = ans + (((C[k][i] * sum[1][i]) % mod) * sum[0][k - i]) % mod;
    return ans % mod;
}

int main()
{
    int t, n, m, k, x, y;
    cin >> t;
    for(int Case = 1; Case <= t; Case++)
    {
        scanf("%d%d%d%d%d", &n, &m, &k, &x, &y);
        init();
        solve(n,k,x,0);
        solve(m,k,y,1);
        printf("Case #%d:\n%I64d\n", Case, getans(k));
    }
}

HDU 4832 Chess

时间: 2024-07-29 22:33:12

HDU 4832 Chess的相关文章

hdu 4832 Chess(dp)

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 193    Accepted Submission(s): 59 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线

HDU 4832 Chess (DP)

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 24    Accepted Submission(s): 10 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线.

HDU 4832 Chess 排列组合 DP

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 351    Accepted Submission(s): 124 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘 上的走法遵循十字

HDU 4832 Chess(DP+组合数)

行列的走法不互相影响,可以分开计算,最后再组合相乘累加即可 1 #include<stdio.h> 2 #include<string.h> 3 int c[1010][1010]; 4 int dpx[1010][1010],x[1010]; 5 int dpy[1010][1010],y[1010]; 6 int n,m,k,x0,y0; 7 void init()//求组合数 8 { 9 memset(c,0,sizeof(c)); 10 for(int i=0;i<1

HDU 4832(DP+计数问题)

HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行,竖用几行,然后相乘累加起来就是答案 代码: #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long ll; const ll MOD = 9999991; const int N = 1005; int t, n, m, k, x, y; ll dp1

HDU 4832 组合计数dp

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 509    Accepted Submission(s): 198 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字

hdu 4832 百度之星初赛二B

把横的和竖的分开考虑 //#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<ma

HDU 5724 Chess(国际象棋)

HDU 5724 Chess(国际象棋) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Description 题目描述 Alice and Bob are playing a special chess game on an n × 20 chessboard. There are several chesses on the chessboard. They can mo

百度之星2017 HDU 6114 Chess 组合数学

Chess 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6114 Description 車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子.一天,小度在棋盘上摆起了许多車--他想知道,在一共N×M个点的矩形棋盘中摆最多个数的車使其互不攻击的方案数.他经过思考,得出了答案.但他仍不满足,想增加一个条件:对于任何一个車A,如果有其他一个車B在它的上方(車B行号小于車A),那么車A必须在車B的右边(車A列号大于車B).现在要问问