【bzoj4321】queue2
2015-11-05 15:27
423 查看
DP,状态想了很久……
设f[i][j][0..1]f[i][j][0..1]表示前i个沙茶有j对是相邻的,其中第i个沙茶和第i-1个沙茶相不相邻。
先考虑第i个沙茶和第i-1个沙茶相邻,f[i][j][1]f[i][j][1]。现在第i个沙茶是新插入进去的,他的插♂入直接导致了他和第i-1个沙茶牵手了(雾),他可以牵第i个沙茶的左手或右手。如果原本第i-1个沙茶和第i-2个沙茶是牵手的,而当前这个沙茶插进去之后强行让他们分手自己再插进去,这就是f[i−1][j][1]f[i-1][j][1],即相邻的沙茶对数仍然是j。又或者他们(哔~),当前沙茶和第i-1个沙茶牵手却不影响第i-2个沙茶,导致沙茶的对数增加了1,即原来是f[i−1][j−1][1]f[i-1][j-1][1]。还有的情况就是第i-1个沙茶没有和第i-2个沙茶牵手,当前沙茶既可以牵他左手又可以牵右手,即为f[i−1][j−1][0]∗2f[i-1][j-1][0]*2
故f[i][j][1]=f[i−1][j][1]+f[i−1][j−1][1]+f[i−1][j−1][0]∗2f[i][j][1]=f[i-1][j][1]+f[i-1][j-1][1]+f[i-1][j-1][0]*2
再考虑第i个沙茶和第i-1个沙茶不相邻,f[i][j][0]f[i][j][0]。
单身狗总是想FFF恩爱狗嘛~
当前的沙茶可以选择在第i-1个沙茶和第i-2个沙茶牵手或不牵手的时候去拆散别人,那么分别有f[i−1][j+1][1]∗jf[i-1][j+1][1]*j和f[i−1][j+1][0]∗(j+1)f[i-1][j+1][0]*(j+1)种选择。又或者他是个好人,一定不会去拆散他们,那么就有f[i−1][j][1]∗(i−j−1)f[i-1][j][1]*(i-j-1)和f[i−1][j][0]∗(i−j−2)f[i-1][j][0]*(i-j-2)种选择。
故f[i][j][0]=f[i−1][j+1][1]∗j+f[i−1][j+1][0]∗(j+1)+f[i−1][j][1]∗(i−j−1)+f[i−1][j][0]∗(i−j−2)f[i][j][0]=f[i-1][j+1][1]*j+f[i-1][j+1][0]*(j+1)+f[i-1][j][1]*(i-j-1)+f[i-1][j][0]*(i-j-2)
时间O(n2)O(n^2),如果用滚动数组空间就是O(n)O(n)。
然而我太懒没有写滚动>_<
另外……
http://oeis.org/A002464
咳咳。
fn=(n+1)fn−1−(n−2)fn−2−(n−5)fn−3+(n−3)fn−4f_n = (n+1)f_{n-1} - (n-2)f_{n-2} - (n-5)f_{n-3} + (n-3)f_{n-4}
我也不知道为什么
学长说可能是容斥的。
设f[i][j][0..1]f[i][j][0..1]表示前i个沙茶有j对是相邻的,其中第i个沙茶和第i-1个沙茶相不相邻。
先考虑第i个沙茶和第i-1个沙茶相邻,f[i][j][1]f[i][j][1]。现在第i个沙茶是新插入进去的,他的插♂入直接导致了他和第i-1个沙茶牵手了(雾),他可以牵第i个沙茶的左手或右手。如果原本第i-1个沙茶和第i-2个沙茶是牵手的,而当前这个沙茶插进去之后强行让他们分手自己再插进去,这就是f[i−1][j][1]f[i-1][j][1],即相邻的沙茶对数仍然是j。又或者他们(哔~),当前沙茶和第i-1个沙茶牵手却不影响第i-2个沙茶,导致沙茶的对数增加了1,即原来是f[i−1][j−1][1]f[i-1][j-1][1]。还有的情况就是第i-1个沙茶没有和第i-2个沙茶牵手,当前沙茶既可以牵他左手又可以牵右手,即为f[i−1][j−1][0]∗2f[i-1][j-1][0]*2
故f[i][j][1]=f[i−1][j][1]+f[i−1][j−1][1]+f[i−1][j−1][0]∗2f[i][j][1]=f[i-1][j][1]+f[i-1][j-1][1]+f[i-1][j-1][0]*2
再考虑第i个沙茶和第i-1个沙茶不相邻,f[i][j][0]f[i][j][0]。
单身狗总是想FFF恩爱狗嘛~
当前的沙茶可以选择在第i-1个沙茶和第i-2个沙茶牵手或不牵手的时候去拆散别人,那么分别有f[i−1][j+1][1]∗jf[i-1][j+1][1]*j和f[i−1][j+1][0]∗(j+1)f[i-1][j+1][0]*(j+1)种选择。又或者他是个好人,一定不会去拆散他们,那么就有f[i−1][j][1]∗(i−j−1)f[i-1][j][1]*(i-j-1)和f[i−1][j][0]∗(i−j−2)f[i-1][j][0]*(i-j-2)种选择。
故f[i][j][0]=f[i−1][j+1][1]∗j+f[i−1][j+1][0]∗(j+1)+f[i−1][j][1]∗(i−j−1)+f[i−1][j][0]∗(i−j−2)f[i][j][0]=f[i-1][j+1][1]*j+f[i-1][j+1][0]*(j+1)+f[i-1][j][1]*(i-j-1)+f[i-1][j][0]*(i-j-2)
时间O(n2)O(n^2),如果用滚动数组空间就是O(n)O(n)。
然而我太懒没有写滚动>_<
另外……
http://oeis.org/A002464
咳咳。
fn=(n+1)fn−1−(n−2)fn−2−(n−5)fn−3+(n−3)fn−4f_n = (n+1)f_{n-1} - (n-2)f_{n-2} - (n-5)f_{n-3} + (n-3)f_{n-4}
我也不知道为什么
学长说可能是容斥的。
[code]#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define per(i,a,b) for(int i=a;i>=b;i--) inline int rd() { char c = getchar(); while (!isdigit(c)) c = getchar() ; int x = c - '0'; while (isdigit(c = getchar())) x = x * 10 + c - '0'; return x; } typedef long long ll; const int mod = 7777777; inline void upd(int&a , ll b) { if (b >= mod) b %= mod ; a += b ; if (a >= mod) a -= mod ; } int n , f[1001][1001][2]; void input() { n = rd(); } void solve() { f[1][0][0] = 1; rep(i , 2 , n) rep(j , 0 , i - 1) { f[i][j][1] = f[i - 1][j][1]; if (j) upd(f[i][j][1] , f[i - 1][j - 1][0] * 2ll + f[i - 1][j - 1][1]); upd(f[i][j][0] , (ll) f[i - 1][j + 1][1] * j); upd(f[i][j][0] , (ll) f[i - 1][j + 1][0] * (j + 1)); upd(f[i][j][0] , (ll) f[i - 1][j][1] * (i - j - 1)); upd(f[i][j][0] , (ll) f[i - 1][j][0] * (i - j - 2)); } printf("%d\n" , f [0][0]); } int main() { #ifndef ONLINE_JUDGE // freopen("data.txt" , "r" , stdin); #endif input(); solve(); return 0; }
相关文章推荐
- Java中栈使用ArrayDeque或LinkedList的性能会更加出色
- 解决EasyUI动态添加标签渲染问题
- Android中Invalidate和postInvalidate和requestLayout的区别
- java String.valueOf()的作用
- OC的UUID生成
- easyui datetimebox setvalue 设置值
- UITextField中限制输入的办法
- UIView 之 Animation 一边上跳 一边旋转
- OpenAL Tutorial - Playing WAV files (No ALUT required!)
- 简易入手SUI
- IOS动画中的枚举UIViewAnimationOptions
- LeetCode/Dynamic Programming/Unique Paths
- IOS UIScrollView
- hibernate 中createQuery与createSQLQuery的用法和区别
- 超简单的 BlueTooth 蓝牙开发实例,打开蓝牙,关闭蓝牙,配对,解除,功能齐全
- iOS开发- UICollectionView详解+实例
- UI设计要学哪些软件
- spark program guide
- hdoj House Building 5538 (数学几何&&搜索)
- [leetcode300] Longest Increasing Subsequence