Luogu 飛揚的小鳥

2022-04-30 02:15:10 字數 3360 閱讀 7927

bfs or dp

#include using

namespace

std;

const

int n = 1e4 + 10

;#define gc getchar()

#define oo 99999999

struct

node_1 p[n];

struct

node_2 m[n];

struct

node ;

intn, m, k;

int answer =oo, maxx;

queue

q;inline

intread()

intup, down;

int vis[n][1000

];inline

void

bfs()

if(up > p[2].d && up < p[2].u && vis[2][up] == 0

) }

while(!q.empty())

int y = topp.y, x =topp.x;

node nxt;

nxt.x = x + 1

; down = y - m[x].d, up = y +m[x].u;

if(down > p[x + 1].d && down < p[x + 1

].u)

else}}

nxt.y =up;

nxt.step =topp.step;

up =min(up, m);

while(up > p[x + 1].d && up < p[x + 1

].u)

else

}if(nxt.y == m) break

; nxt.y +=m[x].u;

up =min(nxt.y, m);}}

}int

main()

bfs();

if(answer != oo) cout << 1

<< "\n"

<

else

return0;

}/*5 5 0

3 32 1

2 32 1

3 2*/

view code

#include#include

#include

#define n 10003

#define m 1003

#define for(i,j,k) for(int i=j;i<=k;++i)

intread()

while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();

return x*l;

}using

namespace

std;

int a[n][m],x[n],y[n],hi[n]; //

a存到當前點的最優步數

short hk[m<<1],wal[m<<1]; //

hk記列,wal記行,這只是迴圈佇列,不要在意變數名

bool fl[n][m],mp[n][m],li[n]; //

fl--某個點有沒有被走過,mp--某個點有沒有管子,li--記錄某一列能不能到

intmain()

r=m;

for(i,

1,m) wal[i]=i; //

第0列入隊

while(l

else

if (a[mo+1][i]>a[mo][ha]+an) a[mo+1][i]=a[mo][ha]+an; //

更新值if (fl[mo][i]&&a[mo][i]<=a[mo][ha]+an)

//重要剪枝!如果當前點頂上有點比他更優那就可以退了

//但是在這之前的迴圈是必要的,因為這時走的點是他頂上那個點走不到的

}

if (!mp[mo+1][m]&&!ff)

else

if (a[mo+1][m]>a[mo][ha]+an+1) a[mo+1][m]=a[mo][ha]+an+1

; }

if (ha-y[mo]>0)

else

if (a[mo+1][jzm]>a[mo][ha]) a[mo+1][jzm]=a[mo][ha];}}

}for(int i=n; i>=0; i--) //

輸出if

(li[i])

printf(

"0\n");

an=0

;

for(int j=i; j>=1; j--) if (hi[j]!=10000) an++;

printf(

"%d\n

",an);

return0;}}

view code

#include#include

#include

using

namespace

std;

const

int maxdp=100000

;int l[10010],h[10010

];int dp[10010][1010

];int x[10010],y[10010

];bool p[10010

];int

main()

l[n]=0

; h[n]=m+1

;

for(i=0; i)

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

}dp[

0][0]=maxdp;

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

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

}dp[i][j]=min(dp[i][j],dp[i-1][j-x[i-1]]+1

); dp[i][j]=min(dp[i][j],dp[i][j-x[i-1]]+1

); }

for(j=max(1,l[i]+1); j<=min(m-y[i-1],h[i]-1); j++)

for(j=l[i]; j>=1; j--)

for(j=h[i]; j<=m; j++)

}int ans=maxdp;

int cnt=k;

for(i=n; i>=1; i--)

if(ans

if(p[i]==true

) }

if(cnt==k)

else

return0;

}

view code

luogu 1941 飛揚的小鳥

這道題對於第13個資料點,不知為什麼f陣列第二位開到2000以下就不能過,求指教 傳送門 乙個小鳥在 n m 的方陣裡,然後有許多管道你們玩過就不多介紹了,然後每乙個位置,點選會上公升,不點選可以下降,點選效果可以疊加。求如果通關的最小點選次數,否則會最多通過多少個管道。就是搜尋,本以為會拿50pt...

Luogu1941 飛揚的小鳥

這題的 dp 還是比較顯然的 聽說是個完全揹包,大概轉移是差不多的 就從當前層順著列舉 j 往大去更新同層的就好了 其實這樣每次往高處轉移的就是下面的字首最小值 值得注意的是題意要模擬的是遊戲 所以顯然不能先掉下去在在同一步中往上飛 所以轉移順序是不能亂的 就是先轉移往上飛的在轉移往下掉的 好像多開...

飛揚的小鳥

顯然的思路,用網路流做。對每個洞拆點,i.j表示第i個洞被通過這個洞的倒數第j隻鳥通過。然後連邊跑費用流。然而邊數太多直接 怎麼辦?注意到i.j沒被流i.j 1就絕不可能被流。因此動態加邊,初始只連所有到x.1的。目前連到x.y,流成功一次加上所有到x.y 1的邊。然後莫名很慢,所以這裡本辣雞加上了...