zoukankan      html  css  js  c++  java
  • bzoj 4321: queue2

    4321: queue2

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 475  Solved: 287
    [Submit][Status][Discuss]

    Description

    n 个沙茶,被编号 1~n。排完队之后,每个沙茶希望,自己的相邻的两
    人只要无一个人的编号和自己的编号相差为 1(+1 或-1)就行; 
    现在想知道,存在多少方案满足沙茶们如此不苛刻的条件。 
     

    Input

    只有一行且为用空格隔开的一个正整数 N,其中 100%的数据满足 1≤N ≤ 1000; 
     
     

    Output

    一个非负整数,表示方案数对 7777777 取模。   
     

    Sample Input

    4

    Sample Output

    2
    样例解释:有两种方案 2 4 1 3 和 3 1 4 2
     
     
    设f[i][j][k]为排完1-i之后,有j对相邻位置差一,并且i是否和i-1相邻的方案数。
    然后随便推一推转移就好了,这里稍微提一下怎么推转移,至于最后的式子看代码就好了。
    首先,我们看一下f[i][j][0]可以转移到哪些状态:
    1.我们在i的两边放i+1,都会让差一的相邻位置+1。
    所以f[i+1][j+1][1]+=2*f[i][j][0]。
    2.我们在j对差一的相邻位置中间放i+1,都会让差一的相邻位置-1。
    并且因为i于i-1不相邻,所以j对里不用减去,并且放完之后i+1和i不相邻,所以就是:
    f[i+1][j-1][0]+=j*f[i][j][0]。
    3.在剩下的i-j-1个空挡里放,不仅i和i+1不相邻,并且相邻差一的不会增多,
    所以f[i+1][j][0]+=(i-j-1)*f[i][j][0]。
     
    f[i][j][1]的情况类似,推一下就好了。
     
    /**************************************************************
    	Problem: 4321
    	User: JYYHH
    	Language: C++
    	Result: Accepted
    	Time:484 ms
    	Memory:9180 kb
    ****************************************************************/
    
    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 1005
    using namespace std;
    const int ha=7777777;
    int f[maxn][maxn][2];
    int n;
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline void dp(){
    	f[1][0][0]=1;
    	for(int i=1;i<n;i++)
    	    for(int j=0;j<i;j++){
    	    	int ans=f[i][j][0];
    	    	if(ans){
    	    		f[i+1][j+1][1]=add(f[i+1][j+1][1],add(ans,ans));
    	    		f[i+1][j][0]=add(f[i+1][j][0],ans*(ll)(i-j-1)%ha);
    	    		if(j) f[i+1][j-1][0]=add(f[i+1][j-1][0],ans*(ll)j%ha);
    			}
    			ans=f[i][j][1];
    			if(ans){
    				f[i+1][j+1][1]=add(f[i+1][j+1][1],ans);
    				f[i+1][j][1]=add(f[i+1][j][1],ans);
    				f[i+1][j][0]=add(f[i+1][j][0],ans*(ll)(i-j)%ha);
    				if(j) f[i+1][j-1][0]=add(f[i+1][j-1][0],ans*(ll)(j-1)%ha);
    			}
    		}
    }
    
    int main(){
    	cin>>n;
    	dp();
    	cout<<f[n][0][0]<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    Python 面向对象(一)
    【Python之搜索引擎】(一)概述
    【Python】回文palindrome——利用字符串反转
    【Python】raw转义字符
    【Python】directory字典类型
    【Python】面向对象编程思想
    【Python】Sublime text 3 搭建Python IDE
    【Python】卸载完Python3 之后 Python2 无法打开IDLE
    【Python】猜数小游戏(文件操作)
    【Python】list和tuple 区别比较
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8504715.html
Copyright © 2011-2022 走看看