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

C. Planar Reflections

题目大意:

给你一个具有衰变值的例子,以及几堵墙,一个衰变值为n的粒子每穿过一堵墙,并且会向相反方向分裂出一个衰减值为n-1的粒子,作为一个新的粒子,给你m堵墙,以及一个衰减值为n的粒子,问你最后一共有多少个粒子,当粒子的衰减值为1时,就不会在分裂新的粒子了。

解题思路:

首先这是cf 的C题,那么应该是涉及到一些基本算法的,大概率是贪心或者dp,那么这个题,题目给了我们一个规则,大致可以根据这些规则,推导出一个递推方程,难点在于对于方向的处理。可以这么想,我们要得到的是最后通过m堵墙的答案,那么我们就dp通过的墙数以及粒子的衰变值,而不是去递推一堵堵具体的墙。
递推方程为:

dp[i][j]=(dp[i-1][m-j]+dp[i][j-1])%mod;

解释一下这个递推方程,衰变值为i的粒子,以及j堵墙,dp[i][j]表示的其实是,一开始衰变值为i的粒子,还要通过j堵墙之后产生的粒子数,一个粒子,通过一堵墙的话,会向相反方向分裂出一个值为j-1的粒子,而这个粒子会通过m-j堵墙,所以是dp[i-1][m-j],同时还会直接穿过墙,继续通过剩下的j-1堵墙,所以dp[i][j]=(dp[i-1][m-j]+dp[i][j-1])%mod;

代码:

#include<bits/stdc++.h>
using namespace std;
long long dp[1005][1005];///dp[i][j],i表示衰变值,j表示还要穿过的墙数
const int mod = 1e9 + 7;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ///一开始没有看懂别人的题解,后来发现, 原来在穿墙方向上,dp是不用做出处理的,只需要表示需要还要穿过的墙数就行了
    ///这样一来,也就没有所谓的正反之分了
        int t ,n,m;
        cin>>t;
        while(t--){
            cin>>m>>n;
            for(int i=1;i<=m;i++)///对衰变值为1的点初始化,因为这种点无论在什么位置,产生的数量只有1
                 dp[1][i]=1;
            for(int i=1;i<=n;i++)///对墙数为0进行初始化,这部分无论衰变值是多少,都是1
                 dp[i][0]=1;
           for(int i=1;i<=n;i++)///分裂是有先后顺序的,所以先遍历衰变值,把一个粒子衰变完成,再讨论其他粒子
               for(int j=1;j<=m;j++)
                   dp[i][j]=(dp[i-1][m-j]+dp[i][j-1])%mod;
           cout<<dp[n][m]<<endl;
        }

}

共勉

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值