zoukankan      html  css  js  c++  java
  • 题解 [HAOI2017]方案数

    题目传送门

    Solution

    我们没有障碍的时候很好做,直接设 (f_{i,j,k}) 表示到 ((x,y,z)) (x)(i) 位为 (1)(y)(j) 位为 (1)(z)(k) 位为 (1) 的方案数。转移显然。

    考虑有障碍。我当时一直没有注意到一个点导致一直没有想出来。我们设 (g_{i}) 表示到第 (i) 个被禁止的点且不经过其他禁止点的方案数。可以得到转移式:

    [g_{i}=f_{i}-sum_{j} g_{j} imes f_{i-j} ]

    这样是对的是因为不会经过两个被禁止的点。

    时间复杂度 (Theta(o^2))

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define int long long
    #define MAXN 75
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    #define ll long long
    #define MAXM 10005
    int g[MAXM];
    ll n,m,r,tot;
    int get (ll x){int res = 0;while (x) res += (x & 1),x >>= 1;return res;}
    struct node{
    	ll x,y,z;
    	int a,b,c,ind;
    	void init(){a = get (x),b = get (y),c = get (z);}
    	void putin(){read (x,y,z),init();}
    	bool operator < (const node &fuc){return x == fuc.x ? (y == fuc.y ? z < fuc.z : y < fuc.y) : x < fuc.x;}
    }p[MAXM];
    
    #define mod 998244353
    int C[MAXN][MAXN],f[MAXN][MAXN][MAXN];
    
    int mul (int a,int b){return 1ll * a * b % mod;}
    int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
    int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;} 
    
    signed main(){
    	read (n,m,r,tot);
    	for (Int i = 1;i <= tot;++ i) p[i].putin(),p[i].ind = i;
    	p[++ tot] = node {n,m,r},p[tot].init();
    	C[0][0] = 1;
    	for (Int i = 1;i <= 65;++ i){
    		C[i][0] = 1;
    		for (Int j = 1;j <= i;++ j) C[i][j] = add (C[i - 1][j],C[i - 1][j - 1]);
    	}
    	f[0][0][0] = 1;
    	for (Int i = 0;i <= 65;++ i)
    		for (Int j = 0;j <= 65;++ j)
    			for (Int k = 0;k <= 65;++ k){
    				for (Int x = 1;x <= i;++ x) f[i][j][k] = add (f[i][j][k],mul (f[i - x][j][k],C[i][x]));
    				for (Int x = 1;x <= j;++ x) f[i][j][k] = add (f[i][j][k],mul (f[i][j - x][k],C[j][x]));
    				for (Int x = 1;x <= k;++ x) f[i][j][k] = add (f[i][j][k],mul (f[i][j][k - x],C[k][x]));
    			}
    	sort (p + 1,p + tot + 1);
    	for (Int i = 1;i <= tot;++ i){
    		g[i] = f[p[i].a][p[i].b][p[i].c];
    		for (Int j = 1;j < i;++ j){
    			if (((p[i].x & p[j].x) == p[j].x) && ((p[i].y & p[j].y) == p[j].y) && ((p[i].z & p[j].z) == p[j].z))
    				g[i] = dec (g[i],mul (g[j],f[p[i].a - p[j].a][p[i].b - p[j].b][p[i].c - p[j].c]));
    		}
    	}
    	write (g[tot]),putchar ('
    ');
     	return 0;
    }
    
  • 相关阅读:
    练习与突破
    HTML input type=file文件选择表单的汇总(一)
    webpack学习之—— Configuration(配置)
    webpack学习之—— Plugins
    webpack学习之—— Loaders
    webpack学习之——Output
    webpack学习之——Entry Points(入口起点)
    CSS3 3D transform变换
    get和post请求的区别
    日期格式之——剩余时间(天,小时,分,秒)的计算方法
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/14159633.html
Copyright © 2011-2022 走看看