SGU 220.Little Bishops(DP)

题意:

给一个n*n的棋盘,放上k个主教(斜走),求能放置的种类总数。



Solution:

一眼看上去感觉是状压DP,发现状态太多,没办法存下来。。。

下面是一个十分巧妙的处理:

将棋盘按照国际象棋的样子分成黑白两部分,再旋转45°,以黑色为例,一行有1,3,5,7。。。5,3,2,1个格子,

可以处理为1,1,3,3,5,5,7。。。

f[i][j]代表第i层,放了j个棋子的方案数,只要预处理出每一行可以放的个数tem[i]

     f[i][j]=f[i-1][j]+f[i-1][j-1]*(tem[i]-j+1),tem[i]>=j;

同样对白色部分如此处理,最后将对应的黑白方案乘起来累加就好了。

注意答案会超过INT

code

#include <iostream>
#include <cstdio>
using namespace std;

long long  f[2][100][100], ans;
int tem[100];
int n, k, tol;

void make (int x) {
    tol = 0;
    for (int t = x; t <= n; t += 2) {
        tem[++tol] = t;
        if (t != n) tem[++tol] = t;
    }
    f[x - 1][0][0] = 1;
    for (int i = 1; i <= tol; i++)
        for (int j = 0; j <= k; j++)
            if (tem[i] >= j) f[x - 1][i][j] = f[x - 1][i - 1][j]+f[x - 1][i - 1][j - 1] * (tem[i] - j + 1);
}
int main() {
    scanf ("%d %d", &n, &k);
    make (1);
    make (2);
    for (int i = 0; i <= k; i++)
        ans += f[1][tol][i] * f[0][2 * n - 1 - tol][k - i];
    printf ("%I64d", ans);
}

时间: 2024-12-28 15:10:51

SGU 220.Little Bishops(DP)的相关文章

SGU 221.Big Bishops(DP)

题意: 给一个n*n(n<=50)的棋盘,放上k个主教(斜走),求能放置的种类总数. Solution : 同SGU 220,加个高精度就好了. code #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; string f[2][250][250], ans;

SGU 220~229

SB题一堆,以后为了提高效率,SB题,一眼题一律不码. 220 Little Bishops 题意:求n*n的棋盘上放K个象的放法, 象可以对角线相互攻击 sb题. 221 Big Bishops 如上,一字未变,加个高精度即可,尼玛我现在高精度都能写错,还是滚回pj吧.. 222. Little Rooks 题意:n*n放车,问方案数.n最大10. 尼玛,真的滚回pj组了!?老子还是读过书的. 223 Little King 题意:如上,把车改成王. 状压直接上. 224. Little Qu

uva 10237 - Bishops(dp)

克里斯·厄姆森 谷歌今天在 Code 大会上发布了新的无人驾驶汽车.该汽车看起来像是有轮子的缆车,它既没有驾驶盘,也没有刹车踏板和加速装置.Re/code 采访了谷歌无人驾驶汽车项目主管克里斯·厄姆森(Chris Urmson),期间谈及该项目革命背后的概念.产品何时上路等问题. 谷歌在过去的 5 年里改装了现成车型去试验无人驾驶技术.除了车顶的旋转激光装置外,它们看上去跟普通车没什么不同.而该公司今天发布的汽车看上去则非常怪异.它们又小又圆,配备各种小型黑色传感器(车顶也有旋转激光装置),用泡

SGU 134.Centroid( 树形dp )

一道入门树dp, 求一棵树的重心...我是有多无聊去写这种题...傻X题写了也没啥卵用以后还是少写好.. ---------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 16009; int sz[maxn], N; in

sgu 131 状压DP

棋盘覆盖(二) 时间限制:1000 ms  |  内存限制:65535 KB 描述 The banquet hall of Computer Scientists' Palace has a rectangular form of the size M x N (1<=M<=9, 1<=N<=9). It is necessary to lay hardwood floors in the hall. There are wood pieces of two forms:1) re

SGU 390-Tickets(数位dp)

题意:有标号l-r的票,要给路人发,当给的票的编号的各数位的总和(可能一个人多张票)不小k时,才开始发给下一个人,求能发多少人. 分析:这个题挺难想的,参考了一下题解,dp[i][sum][left] 长度i 当前数位和sum  前一子树剩余的和 #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack>

SGU 199 Beautiful People(DP+二分)

时间限制:0.25s 空间限制:4M 题意: 有n个人,每个人有两个能力值,只有一个人的两个能力都小于另一个的能力值,这两个人才能共存,求能同时共存的最大人数. Solution: 显然这是一个两个关键字的最长上升序列. 先按照第一种能力值为第一关键字从小到大,第二能力值为第二关键字从大到小排序(为什么?) 然后就是直接用O(nlogn)的DP就好了 (排序的方法是根据O(nlogn)DP算法中所用到的辅助数组的性质...如果对这个算法理解足够的话应该比较容易想到) code(要用C++提交)

[NYIST737]石子合并(一)(区间dp)

题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 很经典的区间dp,发现没有写过题解.最近被hihocoder上几道比赛题难住了,特此再回头重新理解一遍区间dp. 这道题的题意很明确,有一列石子堆,每堆石子都有数量,还有一个操作:相邻两堆石子合并成一堆石子,这个操作的代价是这两堆石子的数目和.要找一个合并次序,使得代价最小,最终输出最小代价. 这个题可以用动态规划,简单分析可以得知,这一列石子堆都可以划分为小区间,每个小区间

基础dp C Monkey and Banana (类最长上升子序列)

题目大意:有一个猴儿和一些种类的箱子,每种类箱子有各自的长宽高,数目有无限个.猴子想把箱子尽可能的堆积起来, 堆积的条件通俗的讲就是放在下面的箱子能够撑得住上面的箱子,按数学建模来说就是放在下面的箱子的长和宽要比放在上 面的要大(严格大于):由于每种箱子虽然数量是无限的,但是肯定不能同种箱子直接累积,因为那样底面的边长就相等了, 这样就是不合法的了,所以每种箱子可以转换成六种情况的不同箱子(分别作为长宽高),之后就是个最长满足条件的高度序 列就行了,即套用最长上升子序列算法思想即可. #incl