題目描述
小生和小森在玩兔子之謎遊戲。有三隻兔子排成一排。知道每只兔子的初始位置,以及三個兔窩的位置。
遊戲的規則是,重複以下步驟k次:選擇兩個不同的兔子a和b,分別位於a和b。a可以跳過b到達2*b-a的點:
跳躍是不允許其他小兔子已經在點2*b-a的位置上:
跳躍也不允許一次跳過乙個以上的兔子:
現在小生和小森想要知道,k次操作之後,能否讓所有兔子都分別跳到乙個兔窩裡面。注意,第i個兔子並不一定要在第i個巢。並且輸出跳法的種數,數值可能很大,要對結果取模1000000007。只要有乙個跳躍是不同的,兩種方式被認為是不同的。
輸入
有多組測試資料:
第一行,包含乙個整數num,表示測試資料的個數。(1<=num<=10)
每組測試資料,
第一行三個整數,第二行三個整數,分別表示兔子的初始位置和兔窩的位置。兩組數值都是嚴格遞增給出。範圍均為[-10^18,10^18]。
最後乙個整數k。[1,100]。
輸出
共num行,
跳躍的種數。
樣例輸入
80 5 8
0 8 11
10 5 8
0 8 11
30 5 8
0 8 11
25 8 58
13 22 64
580 1 2
1 2 3
1005 8 58
20 26 61
5867 281 2348
235 1394 3293
83-1000000000000000000 999999999999999998 999999999999999999
-1000000000000000000 999999999999999999 1000000000000000000
5樣例輸出
15
000537851168
167142023
29這道題一拿到不知道怎麼做,好像只能dfs
但是接著我們發現,三隻兔子有三種操作:兩隻兔子跳到中間(一種情況);乙隻兔子跳到外面(兩隻兔子跳到外面)。
可以把兔子間的跳躍抽象成乙個二插樹形結構
根節點:三隻兔子等距;兩隻兔子就跳不到中間啦
葉節點:中間那只兔子分別跳到左邊和右邊的情況
對於跳躍的方案數,只是詢問在一棵二叉樹上兩個節點間之間用k步跳躍所能達到的方案數
我們用dp[i][j][k]表示初始節點a離lca i步,結束點b離lca j步,還剩下k步時的方案總數
。為了方便處理,我們假設b節點不動(這很重要,也很巧妙)
當i>0時 讓a向上下走dp[i][j][k]+=dp[i-1][j][k-1]+2*dp[i+1][j][k-1]
當i=0時 讓a向上下走(向上走時lca為a)dp[0][j][k]+=dp[0][j+1][k-1]+dp[0][j-1][k-1]+dp[1][j][k-1]
當i=j=0時 讓a向上下走 dp[0][0][k]=dp[0][1][k-1]+dp[1][0][k-1]*2;
根據定義,j>b離lca的距離時dp為0;**借鑑自lhq大神的blog
#include#include#include
#include
using
namespace
std;
typedef
long
long
ll;#define mod 1000000007
const
int n=107
;struct
note
}point,point1,fa[
2][n];
intdp[n][n][n];
intk,deep_a,deep_b;
bool
ok(note s)
note make(note s)
else
}int dp(int i,int j,int
k)
else
if (i==0&&j>0
)
else
if (i>0 && j==0
)
else
if (i==0&&j==0
)
return
dp[i][j][k];
}int
main()
for(int i=1;i<=k&&ok(fa[1][i-1]);i++)
bool flag=1
;
int t1=-1,t2=-1
;
for(int i=0;i<=deep_a&&flag;i++)
for(int j=0;j<=deep_b&&flag;j++)
}if(t1==-1
)
dp[0][0][0]=1
; memset(dp,-1,sizeof
(dp));
printf(
"%d\n
",dp(t1,t2,k));
}return
0;
}
兔子跳躍之謎下
bzoj許可權題,但這個 可免費評測 題目描述 小生和小森在玩兔子之謎遊戲。有三隻兔子排成一排。知道每只兔子的初始位置,以及三個兔窩的位置。遊戲的規則是,重複以下步驟k次 選擇兩個不同的兔子a和b,分別位於a和b。a可以跳過b到達2 b a的點 跳躍是不允許其他小兔子已經在點2 b a的位置上 跳躍...
樹形DP 樹形DP四例
是時候練一下dp了!我的題單 portkey f u,if fu,i 表示以u uu為根節點的子樹中保留i ii條樹枝的最大蘋果數 f u,i max f max f fu,i max這些題是菜,但也不能輕視啊!include using namespace std define in read i...
HLOJ 樹形DP前置 DFS(樹形DP入門)
給定一棵 n nn 個點的樹,根為 t tt求每個點的父親是哪個點,t tt 的父親輸出 0 00第一行兩個整數 n,t n,tn,t接下來 n 1 n 1n 1 行,每行兩個整數 x,y x,yx,y,表示 x,y x,yx,y 之間有一條邊 n nn 行,第 i ii 行乙個整數,表示 i ii...