车的放置

问题描述

有下面这样的一个网格棋盘,a,b,c,d表示了对应边长度,也就是对应格子数。

要在这个棋盘上放K个相互不攻击的车,也就是这K个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。同样只需要输出答案mod 100003后的结果。

输入格式

输入文件place.in的第1行为有5个非负整数a, b, c, d和k。

输出格式

输出文件place.out包括1个正整数,为答案mod 100003后的结果。

样例输入

2 2 2 2 2

样例输出

38

题解

设f[i][j]表示前i行放了j个车的方案数,显然i<=j

对于第i行,有两种情况:放车或不放车。设第i行有x个格子,如果放车,那么前i行放了j-1个车,则第i行可以放的格子数为x-(j-1),根据乘法原理,放车的方案数为f[i-1][j-1]*(x-j+1);如果第i行不放车,那么前i-1行放了j个车,方案数为f[i-1][j-1]。

当i<=b时,f[i][j]=f[i-1][j]+f[i-1][j-1]*(a-j+1)

当b<i<=b+d时,f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a+c-j+1))

初始化怎么办呢?起初我让f[i][0]=1,f[1][1]=a,然而死活算不对,后来我发现只要f[i][1]的值对了,其他的值就对了,所以把f[i][1]初始化一下就行了。

#include <cstdio>
const int maxn=100003;
int a,b,c,d,n,m,f[2005][1005];
int main()
{
    int i,j,k;
    scanf("%d%d%d%d%d",&a,&b,&c,&d,&n);
    m=b+d;
    for (i=1;i<=b;i++)
      f[i][1]=a*i;
    for (i=b+1;i<=m;i++)
      f[i][1]=a*i+c*(i-b);
    for (i=2;i<=b;i++)
      for (j=2;j<=i;j++)
        f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a-j+1))%maxn;
    for (i=b+1;i<=m;i++)
      for (j=2;j<=i;j++)
        f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a+c-j+1))%maxn;
    printf("%d",f[m][n]);
    return 0;
}

原文地址:https://www.cnblogs.com/rabbit1103/p/9007385.html

时间: 2024-10-07 05:28:13

车的放置的相关文章

CH6802车的放置(二分图最大匹配)

题    目    传    送    门    在    这 题目大意 题目都很简短了就不说了--(懒得打) 解题思路 我们把行和列都看作节点,对于每个可以放位置,连一条行到列的边. 我们发现这是一个二分图. 因为车不能互相攻击,对于第一行,只能放一个车,对于每一列也是如此,所以每个节点只有一条连边. 那么就符合二分图匹配中每两条边没有公共节点. 本题就变成求二分图最大匹配的题目. 代码如下: #include <iostream> #include <cstdio> #incl

Uva 11134 Fabled Rooks (问题分解 + 贪心放置)

题意: 给你n*n的棋盘,让放置n个车 使他们之间并不能相互攻击 附加条件是 给定n个车的放置区间 用左上角和右下角的坐标来表示 解题思路: 首先明确 横向的约束和纵向的约束其实并不互相影响 所以可以对横向和纵向单独求解 把问题变成两个一维的区间选点问题来求解 另外 在取点的时候 有贪心的思路在里面 对于n个区间 应该先选择区间中r最小的区间进行放置可放置的点 可以简单认为这是因为r越小的区间 其选择的灵活性就越低. 我刚开始的时候 是采取了先放置区间长度小的 在放置l小的区间 不正确. cod

uva11134 相互不攻击的车

/*uva11134在N*N(1<=N<=5000)的棋盘上放置N个车,使它们相互不攻击.但是车有划定的区间放置.求解一种方案,是的每个车能放置,没有一种满足,输出impossible思路:这种放置车的问题,一般思考到二分图最大匹配上.因为要求出到底放置到哪个位置,所以要记录下来匹配的点.我们发现行和列是可以分类讨论的(因为给定的区间是一个矩形,这样,即使选定了某一行放置,所有的列还是可供选择的)整理一下流程:例如行:对车编号1--N,对行编号1--N;如果一个车i能放置到第j行,我们在i和j

UVA 11134 Fabled Rooks 贪心

题目链接:UVA - 11134 题意描述:在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案. 算法分析:刚开始没有思路,后来看了别人的博客有了一点想法.我们把矩形的行和列分开解决,即n个车首先不能放置在同一行,然后判断n个车不能放置在同一列,如果都满足的话,即有正确的方法,否则就不行.那么怎样解决和判断在不在同一行并且是否可行呢,我们针对行而言,把这些行的坐标存入优先队列,首先取出最上面(行的标号

XVIII Open Cup named after E.V. Pankratiev. GP of Romania

A. Balance 不难发现确定第一行第一列后即可确定全部,列不等式单纯形求解线性规划即可. #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; typedef vector<double>VD; const int N=110; const double eps=1e-9; VD simplex(vector<VD>A, VD b, VD c){

创建型模式:工厂方法

文章首发创建型模式:工厂方法 简介 姓名:工厂方法 英文名:Factory method Pattern 价值观:扩展是我的专属 个人介绍: Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. (定义一个用于创建对象的接口,让子类决定

Atitit.ALT+TAB没反应车and 点击任务栏程序闪烁可是不能切换

Atitit.ALT+TAB没反应车and 点击任务栏程序闪烁可是不能切换 1. 可能你的Alt+Tab键被别人禁用了,试下以下的方法: 1 2. 为什么要禁用Alt+Tab 1 3. ALT+TAB的历史作用 2 4. 解决方式::AltTabTuner1.0.1绿色版(系统设置软件 2 5. 參考 3 1. 可能你的Alt+Tab键被别人禁用了,试下以下的方法: 開始-执行-输入regedit,找到HKEY_CURRENT_USER\Control Panel\Desktop,在右边窗体,双

Atitit.ALT+TAB没反应车and 点击任务栏程序闪烁但是不能切换

Atitit.ALT+TAB没反应车and 点击任务栏程序闪烁但是不能切换 1. 可能你的Alt+Tab键被别人禁用了,试下下面的方法: 1 2. 为什么要禁用Alt+Tab 1 3. ALT+TAB的历史作用 2 4. 解决方案::AltTabTuner1.0.1绿色版(系统设置软件 2 5. 参考 3 1. 可能你的Alt+Tab键被别人禁用了,试下下面的方法: 开始-运行-输入regedit,找到HKEY_CURRENT_USER\Control Panel\Desktop,在右边窗口,双

UVa 639 放车问题

题意:给定一个 n x n 的棋盘,在上面放置车.其中.号表示可放置,X表示墙.在同一行或同一列的两个车,如果它们之间没有X墙挡着,则是不合法的放置.给定一棋盘,最多可以放置车的数量. 思路:枚举所有的格子,看是否可以在此放置.每次放一个车后,修改棋盘的横行.竖列直到X的位置为1,即不可放置.因为要修改棋盘,所以需拷贝一个过来,修改拷贝的.还有一些注意的,如注释,总感觉写得不是很简洁. 还有就是,二维数组做参数时,可以用 char b[][5],  或者 char (*b)[5].但不能是 ch