bzoj4321
queue2
n 个沙茶,被编号 1~n。排完队之后,每个沙茶希望,自己的相邻的两
人只要无一个人的编号和自己的编号相差为 1(+1 或-1)就行;
现在想知道,存在多少方案满足沙茶们如此不苛刻的条件。
Input
Sample Input
只有一行且为用空格隔开的一个正整数 N,其中 100%的数据满足 1≤N ≤ 1000;
Output
一个非负整数,表示方案数对 7777777 取模。
4
Sample Output2
样例解释:有两种方案 2 4 1 3 和 3 1 4 2
sol:超有趣的dp,但自己就是想不出来,然后翻了题解
考虑把n个数字按1~n一个个填过去,而不是按照位置1~n一个个填数字
把数字按照1~n排序,
dp[i][j][0]表示用到i,有j对数相差为1,i与i-1不相邻
dp[i][j][1]表示用到i,有j对数相差为1,i与i-1相邻
题解 https://blog.csdn.net/yjschaf/article/details/72453712
/* 把数字按照1~n排序, dp[i][j][0]表示用到i,有j对数相差为1,i与i-1不相邻 dp[i][j][1]表示用到i,有j对数相差为1,i与i-1相邻 题解 https://blog.csdn.net/yjschaf/article/details/72453712 */ #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const ll N=1005,Mod=7777777; ll n,dp[N][N][2]; inline void Ad(ll &x,ll y) { x+=y; x-=(x>=Mod)?Mod:0; } int main() { int i,j,k; R(n); dp[1][0][0]=1; for(i=2;i<=n;i++) { for(j=0;j<=i-1;j++) { Ad(dp[i][j][0],dp[i-1][j+1][0]*(j+1)%Mod); Ad(dp[i][j][0],dp[i-1][j+1][1]*j%Mod); Ad(dp[i][j][0],dp[i-1][j][0]*(i-j-2)%Mod); Ad(dp[i][j][0],dp[i-1][j][1]*(i-j-1)%Mod); Ad(dp[i][j][1],dp[i-1][j-1][0]*2%Mod); Ad(dp[i][j][1],dp[i-1][j-1][1]); Ad(dp[i][j][1],dp[i-1][j][1]); } } Wl(dp[n][0][0]); return 0; } /* input 4 output 2 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!