為了簡化問題,我們對遊戲規則進行了簡化和改編:
遊戲介面是乙個長為n ,高為 m 的二維平面,其中有k 個管道(忽略管道的寬度)。
小鳥始終在遊戲介面內移動。小鳥從遊戲介面最左邊任意整數高度位置出發,到達遊戲介面最右邊時,遊戲完成。
小鳥每個單位時間沿橫座標方向右移的距離為1 ,豎直移動的距離由玩家控制。如果點選螢幕,小鳥就會上公升一定高度x ,每個單位時間可以點選多次,效果疊加;
如果不點選螢幕,小鳥就會下降一定高度y 。小鳥位於橫座標方向不同位置時,上公升的高度x 和下降的高度y 可能互不相同。
小鳥高度等於0 或者小鳥碰到管道時,遊戲失敗。小鳥高度為 m 時,無法再上公升。
現在,請你判斷是否可以完成遊戲。如果可以 ,輸出最少點選螢幕數;否則,輸出小鳥最多可以通過多少個管道縫隙。
輸入格式:
輸入檔名為 bird.in 。
第1 行有3 個整數n ,m ,k ,分別表示遊戲介面的長度,高度和水管的數量,每兩個
整數之間用乙個空格隔開;
接下來的n 行,每行2 個用乙個空格隔開的整數x 和y ,依次表示在橫座標位置0 ~n- 1
上玩家點選螢幕後,小鳥在下一位置上公升的高度x ,以及在這個位置上玩家不點選螢幕時,
小鳥在下一位置下降的高度y 。
接下來k 行,每行3 個整數p ,l ,h ,每兩個整數之間用乙個空格隔開。每行表示一
個管道,其中p 表示管道的橫座標,l 表示此管道縫隙的下邊沿高度為l ,h 表示管道縫隙
上邊沿的高度(輸入資料保證p 各不相同,但不保證按照大小順序給出)。
輸出格式:
輸出檔名為bird.out 。
共兩行。
第一行,包含乙個整數,如果可以成功完成遊戲,則輸出1 ,否則輸出0 。
第二行,包含乙個整數,如果第一行為1 ,則輸出成功完成遊戲需要最少點選螢幕數,否則,輸出小鳥最多可以通過多少個管道縫隙。
輸入樣例#1: 複製
10 10 6輸出樣例#1: 複製3 9
9 9
1 2
1 3
1 2
1 1
2 1
2 1
1 6
2 2
1 2 7
5 1 5
6 3 5
7 5 8
8 7 9
9 1 3
1輸入樣例#2: 複製6
10 10 4輸出樣例#2: 複製1 2
3 1
2 2
1 8
1 8
3 2
2 1
2 1
2 2
1 2
1 0 2
6 7 9
9 1 4
3 8 10
0【輸入輸出樣例說明】3
如下圖所示,藍色直線表示小鳥的飛行軌跡,紅色直線表示管道。
【資料範圍】
對於30% 的資料:5 ≤ n ≤ 10,5 ≤ m ≤ 10,k = 0 ,保證存在一組最優解使得同一單位時間最多點選螢幕3 次;
對於50% 的資料:5 ≤ n ≤ 2 0 ,5 ≤ m ≤ 10,保證存在一組最優解使得同一單位時間最多點選螢幕3 次;
對於70% 的資料:5 ≤ n ≤ 1000,5 ≤ m ≤ 1 0 0 ;
對於100%的資料:5 ≤ n ≤ 100 0 0 ,5 ≤ m ≤ 1 0 00,0 ≤ k < n ,0題解:
很容易想到70分演算法對吧,最短路什麼,dp都可以,高nm^2,
主要的是怎麼優化的問題,發現f[i][j]可以不用每次o(m)去轉移
因為,每次這樣轉移發現,其實其下面那個點也是被這樣轉移過的。
假設可以向上跳,可以轉化成,先跳到下面最近那個點,在跳上來。
然後轉移就沒多少了,只有從前一列,當前列的兩個轉移,o(1)轉移
但是情況要考慮仔細,不能一開始直接將不可行的解標記為不可到達。
這樣會導致沒有連續跳這種情況,所以應該先處理完這一列在標記為不可到達。
這樣就ok了。
1 #include2 #include3 #include4 #include5 #include6#define inf 2000000009
7using
namespace
std;89
intn,m,k;
10int f[10007][1007
];11
struct
node
12a[10007
];15
struct
node1
16b[10007
];19
20bool
cmp(node1 x,node1 y)
2124
intmain()
2551}52
for(int j=0;j<=a[i].x;j++)
5360
else
break;61
}62for (int j=1;j<=m;j++)
6367
if (b[num].wei==i)
6874
bool check=0;75
for (int j=1;j<=m;j++)
76if (f[i][j]1;break
;}77
if (!check) break;78
else
if (b[num].wei==i) num++;79}
8081
int ans=inf;
82for (int i=1;i<=m;i++)
83 ans=min(ans,f[n][i]);
8485
if (num>k) printf("
1\n%d
",ans);
86else printf("
0\n%d
",num-1
);87 }
P1941 飛揚的小鳥
定義dp i j 表示走到座標 i,j 時的最小點按次數。考慮遞推關係,能走到座標 i,j 一種情況是從前乙個位置下降上公升的轉移是乙個完全揹包,下降是01揹包。include using namespace std define ll long long define inf 0x3f3f3f d...
P1941 飛揚的小鳥
miku 定義 f 為到達 i,j 的最小代價 然後對於從下往上,因為可以點無數次,是個完全揹包,從上往下就一次,01揹包,飛到天花板上的,拽下來 水管特判 include include includeusing namespace std const int maxn 10005 int n,m...
P1941 飛揚的小鳥
動態規劃,設 f i j 表示小鳥到達座標 i j 所要點選螢幕的最少次數,如果小鳥無法到達 i j 則 f i j inf。轉移,考慮小鳥上公升,和下降兩種狀態。因為,在乙個點上公升次數不限,下降只有一次。所以上公升可以用 完全揹包 的狀態轉移,下降用 01揹包 轉移。特判,當小鳥到達頂上 m 時...