[动态规划] NamomoCamp Daily 8

Posted 晁棠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[动态规划] NamomoCamp Daily 8相关的知识,希望对你有一定的参考价值。

NamomoCamp Daily 8

代码源oj网址http://oj.daimayuan.top/course/10/problem/467

题解:

由于 n n n过大,所以正解绝对不是 n 2 n^2 n2的做法,所以我们来考虑 m 2 m^2 m2的做法。

对于一个障碍点 ( i , j ) (i,j) (i,j),从 ( 1 , 1 ) (1,1) (1,1)走到它的方案数是 C i − 1 + j − 1 i − 1 C_i-1+j-1^i-1 Ci1+j1i1个。若我们要走到 ( u , v ) (u,v) (u,v)这个点,障碍点 ( i , j ) (i,j) (i,j)不能走了,那么从障碍点到目标点的方案也不能走了。用 f [ i ] f[i] f[i]表示第 i i i个点的合法路径,假设目标点是 f [ j ] f[j] f[j],那么答案就是 f [ j ] = C x j − 1 + y j − 1 x j − 1 − ( f [ i ] ∗ C x j − x i + y j − y i x j − x i ) f[j]=C_x_j-1+y_j-1^x_j-1-(f[i]*C_x_j-x_i+y_j-y_i^x_j-x_i) f[j]=Cxj1+yj1xj1(f[i]Cxjxi+yjyixjxi)

所以,能够走的方案数=总方案数-不合法方案数。

代码:

代码源
// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int mod = 1e9 + 7;
const int N = 2e6 + 10, M = 3050;
int n, T, m;
int fact[N], infact[N];

struct Point 
	int x, y;
p[N];
int dp[N];

int qsm(int a, int b) 
	int res = 1;
	while (b) 
		if (b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	
	return res % mod;


void init()

	fact[0] = infact[0] = 1;
	ffor(i, 1, 2e6 + 3) 
		fact[i] = fact[i - 1] * i % mod;
		infact[i] = infact[i - 1] * qsm(i, mod - 2) % mod;
	



int C(int b, int a) 
	if (a > b) return 0;
	return fact[b] * infact[a] % mod * infact[b - a] % mod;


void ready()

	IOS;
	cin >> n >> m;
	ffor(i, 1, m) cin >> p[i].x >> p[i].y;
	p[m + 1].x = n; p[m + 1].y = n;
	init();


bool vis[N];

int dfs(int u)

	if (vis[u]) return dp[u];
	vis[u] = true;
	int res = 0;
	ffor(v, 1, m + 1)
	
		if (v == u) continue;
		if (p[v].x <= p[u].x && p[v].y <= p[u].y) 
			res = (res + dfs(v) * C(p[u].x - p[v].x + p[u].y - p[v].y, p[u].x - p[v].x) % mod) % mod;
		
	
	dp[u] = (C(p[u].x - 1 + p[u].y - 1, p[u].x - 1) - res + mod) % mod;
	return dp[u];


void work()

	int ans=dfs(m + 1);
	cout << ans;


signed main()

	ready();
	work();
	return 0;



以上是关于[动态规划] NamomoCamp Daily 8的主要内容,如果未能解决你的问题,请参考以下文章

[LCA] NamomoCamp Daily 3

NamomoCamp Daily 1

[思维] NamomoCamp Daily 5

[思维] NamomoCamp Daily 7

[思维] NamomoCamp Daily 7

[前缀和] NamomoCamp Daily 4