洛谷1002 容斥原理+dfs OR DP

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,sx,sy,xx[]={1,1,2,2,-1,-1,-2,-2,0},yy[]={2,-2,1,-1,2,-2,1,-1,0};
int stk1[25],stk2[25],stk[25],C[45][45],Ans,top;
bool check(int x,int y){return x>=0&&y>=0&&x<=n&&y<=m;}
int solve(int dep){
    int lastx=0,lasty=0,ans=1;
    for(int i=1;i<=dep;i++){
        int tx=stk1[stk[i]]-lastx,ty=stk2[stk[i]]-lasty;
//        printf("tx=%d ty=%d\n",tx,ty);
        ans*=C[tx+ty][tx];
        lastx=stk1[stk[i]],lasty=stk2[stk[i]];
    }
    int tx=n-lastx,ty=m-lasty;
    return ans*C[tx+ty][tx];
}
void dfs(int x,int y,int nw,int dep){
    if(dep&1)Ans-=solve(dep);
    else Ans+=solve(dep);
//    printf("x=%lld y=%lld dep=%lld Ans=%lld\n",x,y,dep,solve(dep));
    for(int i=1;i<=top;i++){
        if(i!=nw&&stk1[i]>=x&&stk2[i]>=y){
            stk[dep+1]=i;
            dfs(stk1[i],stk2[i],i,dep+1);
        }
    }
}
signed main(){
    scanf("%lld%lld%lld%lld",&n,&m,&sx,&sy);
    for(int i=0;i<=40;i++){
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;j++)
            C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    for(int i=0;i<=8;i++){
        int dx=sx+xx[i],dy=sy+yy[i];
        if(check(dx,dy))stk1[++top]=dx,stk2[top]=dy;
    }
    dfs(0,0,0,0);
    printf("%lld\n",Ans);
}
//By SiriusRen
#include <stdio.h>
long long n,m,sx,sy,i,j,vis[25][25],F[25][25],xx[]={1,1,2,2,-1,-1,-2,-2,0},yy[]={2,-2,1,-1,2,-2,1,-1,0};
int check(int x,int y){return x>=0&&y>=0&&x<=n&&y<=m;}
signed main(){
    scanf("%I64d%I64d%I64d%I64d",&n,&m,&sx,&sy);
    for(i=0;i<=8;i++){
        int dx=sx+xx[i],dy=sy+yy[i];
        if(check(dx,dy))vis[dx][dy]=1;
    }
    F[0][0]=1;
    for(i=0;i<=n;i++){
        for(j=0;j<=m;j++)if(!vis[i][j]){
            if(i)F[i][j]+=F[i-1][j];
            if(j)F[i][j]+=F[i][j-1];
        }
    }printf("%I64d\n",F[n][m]);
    return 0;
}
时间: 2024-12-17 15:33:48

洛谷1002 容斥原理+dfs OR DP的相关文章

洛谷 P1784 数独[DFS/回溯]

To 洛谷.1784 数独类似题:CODEVS.4966 简单数独(4*4数独) CODEVS.2924 数独挑战) 题目描述 数独是根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复.每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的. 芬兰一位数学家号称设计出全球最难的“数独游戏”,并刊登在报纸上,让大家去挑战. 这位数学家说,他相信只有“智慧最顶尖”的人才有可能破解这个“数独之谜”.

洛谷 P1270 “访问”美术馆(树形DP)

P1270 “访问”美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer知道每个展室里藏画的数量,并且他精确测量了通过每条走廊的时间.由于经验老到,他拿下一幅画需要5秒的时间.你的任务是编一个程序,计算在警察赶来之前,他最多能偷到多少幅画. 输入输出格式 输入格式: 第1行是警察赶到的时间,以s为单位.第2行描述了艺术馆的结构,是一串非负整数,成对地出现:每一对的第一个

洛谷 P1273 有线电视网(dp)

/* 想了半天没想出状态 自己还是太弱了 QAQ 题目问的是最多供给多少户 一般想法是把这个值定义为状态量 没想出来QAQ....看了看题解的状态 很机智.... f[i][j]表示i的子树 选了j个叶子的最大收益 这样 不亏本就是收益>=0 转移的话 先搜一下这个子树有几个叶子 然后枚举儿子 枚举当前儿子分几个叶子 这里的枚举顺序有套路 从大到小枚举i分几个 从小到大枚举j分几个 这样可以避免 重复选择 注意初始化 */ #include<iostream> #include<c

洛谷P1220关路灯[区间DP]

题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边

洛谷P1156 垃圾陷阱[背包DP]

题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了.另外,卡门可以通过吃一些垃圾来维持自己的生命. 每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间. 假设卡门预先知道了每个垃圾扔下的时间t(0< t<=1000),以及每个垃圾堆放的高度h(1<=h<=25)和吃进该垃圾能维持生命的时间f(

洛谷p1605迷宫 dfs

emmmmm~ 这道题是一道模板深搜吧 题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下左右四种方式,每次只能移动一个方格.数据保证起点上没有障碍. 输入样例 输出样例 [数据规模] 1≤N,M≤5 题目描述 输入输出格式 输入格式: [输入] 第一行N.M和T,N为行,M为列,T为障碍总数.第二行起点坐标SX,SY,终点 坐标FX,FY.接下来

洛谷OJ 2051 中国象棋 DP(计数)

https://www.luogu.org/problem/show?pid=2051 题意:n*m棋盘,n,m<=100 问在棋盘上放炮 使得任意两个炮都互补攻击(即同行或者同列最多放两个)的方法数? 定义状态,dp[i][j][k] 已经放了i行 有j列放一个炮,有k列放2个炮 (并不需要准确知道当前棋盘的状态)状态转移时,按照第i行如何放炮即可 #include <bits/stdc++.h> using namespace std; typedef long long ll; c

AC日记——过河卒 洛谷 1002

题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标表示,A点(0, 0).B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的. 现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步. 输入输出格式 输入格式: 一行四个数据,分别表示B点坐标和马的坐标. 输出格式: 一

洛谷P1220关路灯——区间DP

题目:https://www.luogu.org/problemnew/show/P1220 区间DP. 代码如下: #include<iostream> #include<cstdio> using namespace std; int n,c,pos[55],w[55],sum,s[55][55],dp[55][55][3],INF=10000006; int main() { scanf("%d%d",&n,&c); for(int i=1