2 条题解

  • 0
    @ 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;
    }
    
    • 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
      难度
      3
      标签
      (无)
      递交数
      22
      已通过
      20
      上传者