【題目描述】
為了簡化問題,我們對遊戲規則進行了簡化和改編:
(1)遊戲介面是乙個長為n,高為m的二維平面,其中有k個管道(忽略管道的寬度)。
(2)小鳥始終在遊戲介面內移動。小鳥從遊戲介面最左邊任意整數高度位置出發,到達遊戲介面最右邊時,遊戲完成。
(3)小鳥每個單位時間沿橫座標方向右移的距離為1,豎直移動的距離由玩家控制。如果點選螢幕,小鳥就會上公升一定高度x,每個單位時間可以點選多次,效果疊加;如果不點選螢幕,小鳥就會下降一定高度y。小鳥位於橫座標方向不同位置時,上公升的高度x和下降的高度y可能互不相同。
(4)小鳥高度等於0或者小鳥碰到管道時,遊戲失敗。小鳥高度為m時,無法再上公升。
現在,請你判斷是否可以完成遊戲。如果可以,輸出最少點選螢幕數,否則,輸出小鳥最多可以通過多少個管道縫隙。
【輸入描述】
第一行輸入三個整數n、m、k,分別表示遊戲介面的長度、高度和水管的數量;
接下來n行,每行輸入兩個整數x和y,表示在橫座標位置0~n-1上點選螢幕後,小鳥在下一位置上公升的高度x,以及在這個位置上玩家不點選螢幕時,小鳥在下一位置下降的高度y;
接下來k行,每行輸入三個整數p、l、h,其中p表示管道的橫座標,l表示此管道縫隙的下邊沿高度為l,h表示管道縫隙上邊沿的高度(輸入資料保證p各不相同,但不保證按照大小順序給出)。
【輸出描述】
第一行,如果可以成功完成遊戲,輸出1,否則輸出0;
第二行輸出乙個整數,如果第一行輸出1,則輸出成功完成遊戲需要最少點選螢幕數,否則,輸出小鳥最多可以通過多少個管道縫隙。
【樣例輸入】
樣例1:
10 10 6
3 96 9
1 21 3
1 21 1
2 12 1
1 62 2
1 2 7
5 1 5
6 3 5
7 5 8
8 7 9
9 1 3
樣例2:
10 10 4
1 23 1
2 21 8
1 83 2
2 12 1
2 21 2
1 0 2
6 7 9
9 1 4
3 8 10
【樣例輸出】
樣例1:16
樣例2:03
【資料範圍及提示】
對於30%的資料:5 ≤ n ≤ 10,5 ≤ m ≤ 10,k=0,保證存在一組最優解使得同一單位時間最多點選螢幕3次;
對於50%的資料:5 ≤ n ≤ 20,5 ≤ m ≤ 10,保證存在一組最優解使得同一單位時間最多點選螢幕3次;
對於70%的資料:5 ≤ n ≤ 1000,5 ≤ m ≤ 100;
對於100%的資料:5 ≤ n ≤ 10000,5 ≤ m ≤ 1000,0 ≤ k < n,0 < x < m,0 < y < m,0 < p < n,0 ≤ l < h ≤ m,l+1 < h。
如下圖所示,藍色直線表示小鳥的飛行軌跡,紅色直線表示管道。
源**:#include
#include
#define inf 1000000000
using
namespace
std;
int f[10001][1001]=;
int x[10001],y[10001],up[10001],down[10001
];int
n,m,k;
int main() //
一壺濁酒盡餘歡,今宵也腦殘。
for (int a=0;a)
scanf(
"%d%d
",&x[a],&y[a]);
for (int a=0;a)
int num=0; //
儲存已經通過的管道數。
for (int a=1;a<=n;a++)
for (int b=m-x[a-1];b<=m;b++) //
頂上特判。
f[a][m]=min(f[a][m],min(f[a-1][b],f[a][b])+1
);
for (int b=down[a]+1;b//
來自上方,不可能掉多次。
if (b+y[a-1]<=m)
f[a][b]=min(f[a][b],f[a-1][b+y[a-1
]]);
for (int b=1;b<=down[a];b++) //
給障礙物賦最大值。
f[a][b]=inf;
for (int b=up[a];b<=m;b++) //
同理。 f[a][b]=inf;
bool t(0
);
for (int b=1;b<=m;b++) //
判斷是否有可行解。
if (f[a][b]
if (!t)
else
if (up[a]!=m+1) //
判斷是否有管道。
num++;
}int ans=inf;
for (int a=1;a<=m;a++)
ans=min(ans,f[n][a]);
printf(
"1\n%d
",ans);
return0;
}/*類似於棋盤型dp,注意上公升的次數不限。狀態轉移方程為:
f[i][j]=min(f[i-1][j+y[i-1]],f[i-1][j-x[i-1]]+1,f[i][j-x[i-1]]+1)。
其中完全揹包的垂直疊加取優法值得學習借鑑。
*/
飛揚的小鳥
顯然的思路,用網路流做。對每個洞拆點,i.j表示第i個洞被通過這個洞的倒數第j隻鳥通過。然後連邊跑費用流。然而邊數太多直接 怎麼辦?注意到i.j沒被流i.j 1就絕不可能被流。因此動態加邊,初始只連所有到x.1的。目前連到x.y,流成功一次加上所有到x.y 1的邊。然後莫名很慢,所以這裡本辣雞加上了...
飛揚的小鳥
飛揚的小鳥 這一題開始看到時就知道是dp,但作死打了個dfs,只有75分 卡常 好 includeusing namespace std const int n 10005 const int inf 9999999 int g sum n g up n g down n up n down n n...
飛揚的小鳥
首先這道題爆搜可做,理論上可以拿50分的,但由於windows下棧空間只有3w多,所以只能拿到35分。然後我們考慮dp 應該很容易想到是dp 定義狀態f i j 為在點 i,j 時最少的觸屏次數,然後列舉觸屏次數轉移即可。這樣複雜度是o nm 2 可以拿70分,但這裡很容易犯的的乙個錯誤就是當在螢幕...