飛揚的小鳥

2021-08-28 16:11:49 字數 1151 閱讀 5662

首先這道題爆搜可做,理論上可以拿50分的,但由於windows下棧空間只有3w多,所以只能拿到35分。

然後我們考慮dp(應該很容易想到是dp),定義狀態f[i][j]為在點(i,j)時最少的觸屏次數,然後列舉觸屏次數轉移即可。這樣複雜度是o(nm^2),可以拿70分,但這裡很容易犯的的乙個錯誤就是當在螢幕最上端時,要特判。

正解:對於f[i][j]=min(f[i][j], f[i-1][j-t*x[i-1]]+t),能夠發現等價於dp[i][j]=min(dp[i][j], min(dp[i-1][j-x[i-1]], dp[i][j-x[i-1]])+1),其實就是對於(i,j)這個點,要麼就是從下面剛好x[i-1]的距離轉移而來,要麼就是從更下面跳了幾倍的x[i-1]轉移而來。所以複雜度變成了o(nm)。然後還有需要注意的一點就是頂端要特判,即若是在頂端的話,要在前面的基礎上,考慮上在x[i-1]之內的情況,還有調到這裡面的情況,因為從這裡也是可以轉移到頂端的。

code:

//80分dp,大體方法沒有錯誤,在一些細節上有錯,懶得調了

#include#includeusing namespace std;

const int n=1e4+10, m=1e3+10, k=1e4+10, inf=0x3f3f3f3f;

int n, m ,k, far, cnt, ans=inf, dp[n][m];

int x[n], y[n], p[k], l[k], h[k];

bool block[n][m];

int main()

for (int i=0; i<=n; i++)

block[i][0]=true;

for (int i=0; i<=m; i++)

if (!block[0][i]) dp[0][i]=0;

for (int i=1; i<=n; i++)

if (j-x[i-1]>=0)

if (j+y[i-1]<=m)

}} }

for (int i=1; i<=m; i++)

ans=min(dp[n][i], ans);

if (ans==inf)

else cout << "1" << endl << ans;

return 0;

}

飛揚的小鳥

顯然的思路,用網路流做。對每個洞拆點,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...

飛揚的小鳥

題目描述 為了簡化問題,我們對遊戲規則進行了簡化和改編 1 遊戲介面是乙個長為n,高為m的二維平面,其中有k個管道 忽略管道的寬度 2 小鳥始終在遊戲介面內移動。小鳥從遊戲介面最左邊任意整數高度位置出發,到達遊戲介面最右邊時,遊戲完成。3 小鳥每個單位時間沿橫座標方向右移的距離為1,豎直移動的距離由...