C. Planar Reflections

C. Planar Reflections

题意:

给定一个可以穿越墙体的微观粒子(寿命为 k),但是每穿越一次墙体会产生一个反向寿命为 k−1 的粒子。(如果粒子寿命为1则不再产生反向粒子,即不存在寿命小于1的粒子)
问最后有多少粒子飞出
结合数据 2 3 和下图理解看
在这里插入图片描述

题解:

其实就是推导公式:
n为还要穿多少个墙,k为当前能量,cur为方向(1位向右)
最后退出公式:
dfs(int n,int k,int cur) = dfs(n-1,k,cur)+dfs(x-n,k-1,cur^1)
超时!
我用了dp优化
超时!
。。。。
在这里插入图片描述
题解
然后看了别人的题解
本质思路一样都是推式子,但是人家有剪枝
solve(cur,k,dir)
cur为该粒子经过了多少强,k为能量,dir为方向
(好像和我定义的差不多)
然后根据不同的方向分情况,详细看代码把
我也说不上来比我的快多少
第一个是我的,在本地运行出不来结果
第二个是正确答案的
等会。。。我交到cf后,A了????在这里插入图片描述
最上面是网上的ac代码,最下面是我的
在这里插入图片描述

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int mod=1e9+7;
const int maxn=1e3+8;
int dp[maxn][maxn][3];
int x,y;
int dfs(int n,int k,int cur)
{
    
    
	if(n==0)return 1;
	if(k==1)return 1;
	if(dp[n][k][cur]!=-1)return dp[n][k][cur];
	
//	if(n==1)//如果遇到最后一个墙 
//	{
    
    
//		return ((dp[n-1][k][cur]=dfs(n-1,k,cur))%mod+(dp[x-n][k-1][cur^1]=dfs(x-n,k-1,cur^1))%mod)%mod;
//	}
//	else if(n==x)//如果遇到第一个墙 
//	{
    
    
//		return ((dp[n-1][k][cur]=dfs(n-1,k,cur))%mod+(dp[0][k-1][cur^1]=dfs(0,k-1,cur^1))%mod)%mod;
//	}
	int ans1=dfs(n-1,k,cur)%mod;
//	dp[n-1][k][cur]=ans1;
	int ans2=dfs(x-n,k-1,cur^1)%mod;
//	dp[x-n][k-1][cur^1]=ans2;
	dp[n][k][cur]=(ans1+ans2)%mod;
	return (ans1+ans2)%mod;
}
int main()
{
    
    
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
    
    
		memset(dp,-1,sizeof(dp));
		cin>>x>>y;
		cout<<dfs(x,y,1)%mod<<endl;
	}
	return 0;
}

const int mod = 1e9 + 7;
int n, k;
int dp[1010][1010][2];
int solve(int cur, int k, int dir) {
    
    
    if (k == 1) return 1;
    // 非 -1 说明已经计算过了
    if (dp[cur][k][dir] != -1) return dp[cur][k][dir];
    int ans = 2;  // 本身和穿过墙的复制体
    if (dir == 1) {
    
    
        if (cur < n) ans += solve(cur + 1, k, dir) - 1;
        ans %= mod;
        if (cur > 1) ans += solve(cur - 1, k - 1, 1 - dir) - 1;
        ans %= mod;
        dp[cur][k][dir] = ans;
    } else {
    
    
        if (cur > 1) ans += solve(cur - 1, k, dir) - 1;
        ans %= mod;
        if (cur < n) ans += solve(cur + 1, k - 1, 1 - dir) - 1;
        ans %= mod;
        dp[cur][k][dir] = ans;
    }
    return ans;
}
int main() {
    
    
    ios_base::sync_with_stdio(false), cin.tie(0);
    int _;
    for (cin >> _; _--;) {
    
    
        cin >> n >> k;
        memset(dp, -1, sizeof dp);
        cout << solve(1, k, 1) << '\n';
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35975367/article/details/115332980
今日推荐