HDU 1820 / uva 861 Little Bishops

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1820

题意:给你一个n*n的棋盘,让你放k个象,求方法数

象的攻击路线是斜的,所以我们可以将棋盘旋转45°,这样攻击路线就成了水平,象就变成了车

之后可以发现,如果将棋盘分为黑白格子,黑白棋子之间是无法互相攻击的,那我们就可以将他们分开考虑

把棋盘处理成2个下面的图形

设dp[i][j]表示前i行放了j个车的方法数,c[i]表示第i行可以放置的棋子数量,那么转移方程为:

dp[i][j] = dp[i-1][j] + dp[i-1][j-1] * (c[i] - (j - 1))

需要注意的是c数组应该是增序的,这样才能保证前面的j-1行放了车,对应这一行就有j-1个位

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int N=70;
int n,k;
int c1[N],c2[N],dp1[10][N],dp2[10][N];
void init()//将棋盘分为黑白色,再将棋盘旋转45°
{
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if ((i+j)&1)
                c2[(i+j)>>1]++;//第(i+j)/2斜行有几个格子
            else c1[(i+j)>>1]++;
}
void solve(int dp[N][N],int c[N])
{
    for(int i=0;i<=n;i++)
        dp[i][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=c[i];j++)
            dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(c[i]-j+1);
}
int main()
{
    while(scanf("%d%d",&n,&k)&&n+k)
    {
        init();
        sort(c1+1,c1+1+n);
        sort(c2+1,c2+n);
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        solve(dp1,c1);
        solve(dp2,c2);
        int ans=0;
        for(int i=0;i<=k;i++)
            ans+=dp1[n][i]*dp2[n-1][k-i];
        printf("%d\n",ans);
    }
    return 0;
}

  

时间: 2024-10-13 12:23:41

HDU 1820 / uva 861 Little Bishops的相关文章

UVA 861 Little Bishops

https://vjudge.net/problem/UVA-861 题意: 在n*n棋盘上方k个互不攻击的象,求方案数 若两个象在同意对角线上,则会互相攻击 将棋盘黑白染色,则黑格不会攻击白格,白格不会攻击黑格 所以黑白格分开考虑 最终答案= Σ 黑格放i个*白格放k-i个 将所有黑格抽离出来,旋转45° 这样对角线方向就变成了水平方向和竖直方向 问题转化成了 每一行每一列至多放1个 在按每行格子数量从小到大排序 这样每行依次为 2个.2个.4个.4个.6个.6个.8个.8个…… 或者每行一次

HDU 4089 &amp;&amp; UVa 1498 Activation 带环的概率DP

要在HDU上交的话,要用滚动数组优化一下空间. 这道题想了很久,也算是想明白了,就好好写一下吧. P1:激活游戏失败,再次尝试. P2:连接失服务器败,从队首排到队尾. P3:激活游戏成功,队首的人出队. P4:服务器down掉,所有人都不能激活了. 设d(i, j)表示i个人排队,主人公排在第j位,发生所求事件的概率. d(i, 1) = P1 d(i, 1) + P2 d(i, i) + P4 //分别对应激活失败,重新尝试:连接失败排到队尾:服务器down掉 特殊地可以直接计算出 d(1,

hdu 1069 &amp;uva 437

题意:给出多种a*b*c的箱子,每种箱子有多个每个箱子底面如果长和宽均小于另一个箱子的低面,那么这个箱子那么可以放在那个箱子上面 请输出箱子能够排列的最大的高度 分析:一种箱子最多有6种有效状态,那么把每个箱子拆分为6个箱子,(a,b,c)分别表示长宽高 那么比较一个箱子是否能放在另一个箱子提供了方便,如果一个箱子底面积小于另一个,那么必然不能放在下面,按照箱子底面积排序 dp[i]表示选第i个箱子的最大高度,dp[i]=max(dp[i],dp[j]+h[i])j<i

hdu 2771(uva 12171) Sculpture bfs+离散化

题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处在于求整个雕塑的外表面积和雕塑内部可能出现四个长方体所搭成的空心.空心不能计算到表面积中,可是计算整体积却要计入,于是直接bfs或者dfs不优点理.于是,能够想到直接统计整个雕塑外围的全部小方块.就可以非常方便地求出雕塑地表面积和体积(雕塑地整体积==整个空间地体积-外围想方块的体积),另一点就是因

hdu 2769 uva 12169 Disgruntled Judge 拓展欧几里德

//数据是有多水 连 10^10的枚举都能过 关于拓展欧几里德:大概就是x1=y2,y1=x2-[a/b]y2,按这个规律递归到gcd(a,0)的形式,此时公因数为a,方程也变为a*x+0*y=gcd(a,0)的形式,显然解为x=1,y=0,然后再递归回去就能得到解(a*x+b*y=gcd(a,b)的解) 1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm&g

HDU 1619 &amp; UVA 116 Unidirectional TSP(树形dp,入门 , 数塔变形)

Unidirectional TSP Description Background Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Travelin

国际象棋

容斥原理的应用小象: UVA 861在国际象棋的规定中,象只能从他所在的位置走对角线,如果两只象处于同一斜线上,他们将攻击对方,现给定2个数字n和k,在n*n的棋盘放k个不互相攻击放入小象有多少种放法? (1=<n<=8)(1=<k<=65)将棋盘的黑格抽出,剩下的白格子旋转45度,压缩,使得所有位于对角线上的棋子位于一行 ,称之为白棋盘R_w: 黑棋盘同样处理 R_b如果在白格子里放i个棋子,在黑格子里放(k-i)个棋子,则由乘法定理:R=R_w(i)*R_b(k-i)R[i][

计划,,留

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 一.<算法竞赛入门经典> 刘汝佳 (UVaOJ 351道题) 以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html "AOAPC I"

算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发.   一.UVaOJ http://uva.onlinejudge.org  西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ.   二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html   "AO