CodeCraft-21 and Codeforces Round #711 (Div. 2) C. Planar Reflections (DP)

-
题意:有\(n\)块板子,一个能量为\(k\)的粒子,粒子可以直接穿过板子,当粒子穿过一个板子时,会产生一个反方向的能量为\(k-1\)的粒子,不存在能量为\(0\)的粒子,问你将能量为\(k\)的粒子从最左边向板子射出时,会产生多少粒子?
-
题解:我们记\(dp[i][j]\),表示能量为\(i\)且要穿过\(j\)个板子的粒子能产生的粒子数,那么当它穿过一个板子时,会有它自己\(dp[i][j-1]\),和产生的新粒子\(dp[i-1][n-j]\),所以可以写出状态转移方程:\(dp[i][j]=dp[i][j-1]+dp[i-1][n-j]\).
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int dp[1005][1005]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int _; cin>>_; while(_--){ int n,k; cin>>n>>k; rep(i,1,n) dp[1][i]=1; rep(i,1,k) dp[i][0]=1; rep(i,1,k){ rep(j,1,n){ dp[i][j]=(dp[i][j-1]+dp[i-1][n-j])%mod; } } cout<<dp[k][n]<<'\n'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号