凡人修c传(十七)CodeCraft-21 and Codeforces Round #711 (Div. 2)C. Planar Reflections

       题目大意:

高朗在一个神秘的宇宙中长大。他面对n个连续的二维平面。他向这些平面发射了一个k岁的衰变粒子。一个粒子可以直接穿过一个平面,但是,每个平面都会产生一个粒子的相同副本,以相反的方向运动,衰减年龄为k−1。如果一个粒子的衰变年龄等于1,它将不会产生副本。例如,如果有两个平面,一个粒子衰变年龄为3(向右),过程如下:(这里,D(x)指的是一个衰变年龄为x的单个粒子)

第一个平面向左生成一个D(2),并让D(3)继续向右;
第二个平面向左生成一个D(2),并让D(3)继续向右;
第一个平面让D(2)继续向左,并向右产生D(1);
第二个平面让D(1)继续向右移动(D(1)不能产生任何副本)。
总的来说,粒子的最终多集S为{D(3),D(2),D(2),D(1)}。(请参阅注释以获得该测试用例的可视化解释。)当飞机数量过多时,高朗无法应对这种复杂的情况。在给定n和k的情况下,帮助Gaurang找到多集S的大小。由于多集的大小可能非常大,所以必须对其取109+7的模输出。

注:粒子可以在两个平面之间来回运动而不相互碰撞。

emmm,这是一道状态转移的dp题。要注意状态的转移有方向,本轮向固定方向飞的例子继承的是上一轮向相反方向飞的粒子。

        注:特殊的情况在于最开始的时候。我们假设粒子是往右飞的,那么他从左边第一个板反弹的情况要考虑上。(后续的反弹不会存在这种情况)。在加上最开始的第一个粒子,所以最后的答案要+2。

代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<math.h>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
typedef long long ll;
using namespace std;
ll dp[1005][1005][3];
ll N=1e9+7;
int main() {
	ios::sync_with_stdio(false);
	cin.tie();
	cout.tie();
	ll t;
	cin>>t;
	while(t--){
		memset(dp,0,sizeof dp);
		ll n,m;
		cin>>n>>m;
		if(m==1){
			cout<<1<<"\n";
			continue;
		}
		for(int i=1;i<=n;i++){
			dp[m][i][1]=1;
		}
		ll an=0;
		for(int i=m-1;i>=1;i--){
			dp[i][n][0]=dp[i+1][n-1][1];
			for(int j=n;j>=1;j--){
				dp[i][j][0]=(dp[i+1][j-1][1]+dp[i][j+1][0])%N;
			}
			an=(dp[i][1][0]+an)%N;
//			cout<<"\n";
			for(int j=1;j<=n;j++){
				dp[i][j][1]=(dp[i+1][j+1][0]+dp[i][j-1][1])%N;
			}
			an=(an+dp[i][n][1])%N;
//			cout<<"\n";
		}
		
//		for(int i=1;i<=n;i++){
//			an=(an+(dp[1][i][0]+dp[1][i][1])%N)%N;
//		}
		an=(an+2)%N;
		cout<<an<<"\n";
		
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值