結果
| 問題 |
No.93 ペガサス
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2014-12-09 04:54:31 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 24 ms / 5,000 ms |
| コード長 | 2,661 bytes |
| コンパイル時間 | 1,102 ms |
| コンパイル使用メモリ | 160,464 KB |
| 実行使用メモリ | 22,784 KB |
| 最終ジャッジ日時 | 2024-06-11 18:47:58 |
| 合計ジャッジ時間 | 1,916 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 16 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define REP(i, n) for(int(i)=0;(i)<(n);++(i))
const int MOD = 1000000007;
ll dp[1010][1010][2][2];
int main(){
int N;
cin >> N;
dp[0][0][0][0] = 1;
REP(n,N){
const int mm = n+1; // 置ける場所の数
REP(k,n+1){
int m = mm;
if(n<2){
// 現在の置いている数が2個未満ならどこに置いてもいい
dp[n+1][max(k-1,0)][0][0] += dp[n][k][0][0] * k; // 減少
dp[n+1][k ][0][0] += dp[n][k][0][0] * (m-k); // 維持
continue;
}
m = mm;
dp[n+1][k+1 ][0][1] += dp[n][k][0][0] * 2; m-=2; // 増加 [n-1]の両隣2個
dp[n+1][max(k-1,0)][0][0] += dp[n][k][0][0] * k; m-=k; // 減少 (k個)
dp[n+1][k ][0][0] += dp[n][k][0][0] * m; // 維持
if(k == 0) continue;
// [n-2,n]がある場合
m = mm;
dp[n+1][k+1][1][1] += dp[n][k][0][1] * 2; m-=2; // 増加 [n-1]の両隣2個
dp[n+1][k-1][0][0] += dp[n][k][0][1] * 1; m-=1; // 減少 [n-2,n]の間
dp[n+1][k-1][1][0] += dp[n][k][0][1] * (k-1); m-=k-1; // 減少 [n-2,n]以外の間(k-1個)
dp[n+1][k ][1][0] += dp[n][k][0][1] * m; // 維持
// [n-3,n-1]がある場合
m = mm;
dp[n+1][k+1][0][1] += dp[n][k][1][0] * 1; m-=1; // 増加 [n-1]の片隣1個
dp[n+1][k ][0][1] += dp[n][k][1][0] * 1; m-=1; // 維持 [n-1]の片隣かつ[n-1,n-3]の間1個
dp[n+1][k-1][0][0] += dp[n][k][1][0] * (k-1); m-=k-1; // 減少 [n-3,n-1]以外の間(k-1個)
dp[n+1][k ][0][0] += dp[n][k][1][0] * m; // 維持
// [n-2,n],[n-3,n-1]がある場合
m = mm;
dp[n+1][k+1][1][1] += dp[n][k][1][1] * 1; m-=1; // 増加 [n-1]の片隣1個
dp[n+1][k ][1][1] += dp[n][k][1][1] * 1; m-=1; // 維持 [n-1]の片隣かつ[n-1,n-3]の間1個
dp[n+1][k-1][0][0] += dp[n][k][1][1] * 1; m-=1; // 減少 [n-2,n]の間
dp[n+1][k-1][1][0] += dp[n][k][1][1] * (k-2); m-=k-2; // 減少 [n-2,n],[n-3,n-1]以外の間(k-2個)
dp[n+1][k ][1][0] += dp[n][k][1][1] * m; // 維持
}
REP(k,n+1){
REP(a,2)REP(b,2) dp[n+1][k][a][b] %= MOD;
}
}
cout << dp[N][0][0][0] << endl;
return 0;
}