C. Two Arrays
You are given two integers nn and mm. Calculate the number of pairs of arrays (a,b)(a,b) such that:
- the length of both arrays is equal to mm;
- each element of each array is an integer between 11 and nn (inclusive);
- ai≤biai≤bi for any index ii from 11 to mm;
- array aa is sorted in non-descending order;
- array bb is sorted in non-ascending order.
As the result can be very large, you should print it modulo 109+7109+7.
The only line contains two integers nn and mm (1≤n≤10001≤n≤1000, 1≤m≤101≤m≤10).
Print one integer – the number of arrays aa and bb satisfying the conditions described above modulo 109+7109+7.
2 2
5
10 1
55
723 9
157557417
In the first test there are 55 suitable arrays:
- a=[1,1],b=[2,2]
- a=[1,2],b=[2,2]
- a=[2,2],b=[2,2]
- a=[1,1],b=[2,1]
- a=[1,1],b=[1,1]
可以将题目要求转换为:
1、长度为2*m
2、ci的取值范围为[1,n]
3、序列c非递减
我想了好久终于想明白dp转移方程的道理:
dp[i][j]表示满足以下条件的序列个数:
1、长度为i
2、第一个数为j
3、序列非递减,
那么,dp[i][j]=(dp[i][j + 1] + dp[i - 1][j]) % mod
比如在样例2中,i=2,j=10的时候,如何推出目前的序列数量呢?i=1,j=9的时候,只有{9}这种情况;i=2,j=10的时候,只有{10,10}这种情况
i=1,j=9到i=2,j=9,只需要在i=1,j=9所构成的序列中把序列中任意一个数重复一遍即{9,9}这种情况;
而i=2,j=10到i=2,j=9,只需要在i=2,j=9所构成的序列里,在最前面加上这个数就满足了题目的要求:{9,10}。
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> #include <queue> #include <map> #include <sstream> #include <cstdio> #include <cstring> #include <numeric> #include <cmath> #include <iomanip> #include <deque> #include <bitset> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h> //#include <xfunctional> #define ll long long #define PII pair<int, int> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dec(i,a,b) for(int i=a;i>=b;i--) #define pb push_back #define mk make_pair using namespace std; int dir1[6][2] = { { 0,1 } ,{ 0,-1 },{ 1,0 },{ -1,0 },{ 1,1 },{ -1,1 } }; int dir2[6][2] = { { 0,1 } ,{ 0,-1 },{ 1,0 },{ -1,0 },{ 1,-1 },{ -1,-1 } }; const long long INF = 0x7f7f7f7f7f7f7f7f; const int inf = 0x3f3f3f3f; const double pi = 3.14159265358979; const int mod = 1000000007; const int N = 1005; //if(x<0 || x>=r || y<0 || y>=c) inline ll read() { ll x = 0; bool f = true; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = false; c = getchar(); } while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); return f ? x : -x; } ll gcd(ll m, ll n) { return n == 0 ? m : gcd(n, m % n); } const ll mo = 1e9 + 7; ll dp[22][1100]; int main() { int n, m; cin >> n >> m; m <<= 1; for (int i = 1; i <= n; i++) dp[1][i] = 1; for (int i = 2; i <= m; i++) for (int j = n; j>0; j--) dp[i][j] = (dp[i][j + 1] + dp[i - 1][j]) % mo; ll ans = 0; for (int i = 1; i <= n; i++) ans = (ans + dp[m][i]) % mo; cout << ans << endl; return 0; }