bfs or dp
#include usingview codenamespace
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*/
#include#includeview code#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;}}
#include#includeview code#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;
}
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的邊。然後莫名很慢,所以這裡本辣雞加上了...