4 条题解

  • 2
    @ 2024-3-11 20:38:23

    dpi,jdp_{i,j} 表示经过 ii 轮传到 jj 的方案数,一开始,dp0,1=1dp_{0,1} = 1

    随后开始转移,容易得到 dpi,j=dpi1,l+dpi1,rdp_{i,j} = dp_{i-1,l} + dp_{i-1,r},其中 llrr 为其左边、右边的人的编号。

    因为围成了一个,所以需要进行环处理。

    因为题解区已经有 dpdp 了,因此下面的参考代码为记搜。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define rep(i,x,y) for(int i=x;i<=y;i++)
    #define rrep(i,x,y) for(int i=x;i>=y;i--)
    #define sc scanf
    #define pr printf
    
    const int N=1005;
    int l,r,n,m,dp[N][N];
    
    inline int dfs(int i,int j){
      if(!i&&j==1) return dp[0][1]=1;//初始值。
      if(!i) return 0;//否则,如果轮数为 0,答案一定是 0。
      if(dp[i][j]!=-1) return dp[i][j];//记搜。
      int l=(j-1+n)%n,r=(j+1)%n;//确定左、右边的人的编号。
      if(!l) l=n;
      if(!r) r=n;//环处理。
      return dp[i][j]=dfs(i-1,l)+dfs(i-1,r);//状态转移。
    }
    signed main(){
      memset(dp,-1,sizeof(dp));
      
      sc("%lld%lld",&n,&m);
      pr("%lld\n",dfs(m,1));
      return 0;
    }
    
    • 1
      @ 2025-11-29 14:01:53
      #include<bits/stdc++.h>
      #define int long long
      #define xh(a,b,c) for(int a=b;a<=c;a++)
      using namespace std;
      int n,m,ans;
      int f[40][40];
      bool t[40][40];
      int dfs(int now,int k){
      	if(k==m+1){
      		if(now==1)return 1;
      		else return 0;
      	}
      	if(t[now][k])return f[now][k];
      	else{
      		t[now][k]=1;
      		return f[now][k]=dfs((now-1>0)?now-1:n,k+1)+dfs((now+1<=n)?now+1:1,k+1);
      	} 
      }
      signed main(){
      	cin>>n>>m;
      	cout<<dfs(1,1);
      	return 0;
      } 
      
      • 1
        @ 2025-11-29 14:01:40
        
        
        • 0
          @ 2022-7-27 12:15:36
          #include<bits/stdc++.h>
          using namespace std;
          long n,j,f[1005][1005],i,m;
          long read()
          {
          	long x=0,f=1;
          	char ch=getchar();
          	while(ch<'0'||ch>'9'){
          		if(ch=='-')f=-1;
          		ch=getchar();
          	}
          	while(ch>='0'&&ch<='9')
          	{
          		x=x*10+(ch-'0');
          		ch=getchar();
          	}
          	return x*f;
          }
          void write(long x) {
          	if(x<0){
          		putchar('-');
          		write(-x);
          		return;
          	}
          	if(x>=10)write(x/10);
          	putchar(x%10+'0');
          }
          int main()
          {
          	n=read();m=read();
          	f[1][0]=1;
          	for(i=1;i<=m;i++)
          	{
          		f[1][i]=f[2][i-1]+f[n][i-1];
          		f[n][i]=f[1][i-1]+f[n-1][i-1];
          		for(j=2;j<n;j++)f[j][i]=f[j-1][i-1]+f[j+1][i-1];//动态转移方程
          	}
          	write(f[1][m]);
          	return 0;
          }
          • 1

          信息

          ID
          58
          时间
          1000ms
          内存
          256MiB
          难度
          1
          标签
          (无)
          递交数
          66
          已通过
          46
          上传者