P1941-飞扬的小鸟【dp】
生活随笔
收集整理的這篇文章主要介紹了
P1941-飞扬的小鸟【dp】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.org/problemnew/show/P1941
題目大意
n?mn*mn?m的場地,一只鳥,在iii格點擊一次升XiX_iXi?格(可以點擊多次),不點擊掉YiY_iYi?格。不能落地,最高mmm格,然后不能撞到地圖上的一些管子。
求是否能夠過關,如果能輸出最少點擊次數(shù),否則輸出能過多少個管子。
解題思路
設fi,jf_{i,j}fi,j?表示到(i,j)(i,j)(i,j)位置時,最少點擊次數(shù)。然后轉移
首先是掉落
fi+1,j?downi+1=fi,jf_{i+1,j-down_{i+1}}=f_{i,j}fi+1,j?downi+1??=fi,j?
然后考慮上升,因為可以點擊多次,我們可以用多重背包的方法
fi+1,max{j+upi+1,m}=max{fi,j,fi+1,j}f_{i+1,max\{j+up_{i+1},m\}}=max\{f_{i,j},f_{i+1,j}\}fi+1,max{j+upi+1?,m}?=max{fi,j?,fi+1,j?}
之后將管子位置的fi,jf_{i,j}fi,j?賦值為infinfinf就不會影響到后面的轉移了。
codecodecode
#include<cstdio> #include<algorithm> #include<cstring> #define upa min(j+up[i+1],m) using namespace std; const int N=11000,M=1100; struct node{int x,down,up; }g[N]; int n,m,k,l,ans,mins=2147483647; int up[N],down[N],f[N][M]; bool cmp(node x,node y) {return x.x<y.x;} int main() {scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++)scanf("%d%d",&up[i],&down[i]);for(int i=1;i<=k;i++)scanf("%d%d%d",&g[i].x,&g[i].down,&g[i].up);sort(g+1,g+1+k,cmp);l=1;memset(f,0x3f,sizeof(f));memset(f[0],0,sizeof(f[0]));for(int i=0;i<=n;i++){if(g[l].x==i&&l<=k){for(int j=1;j<=g[l].down;j++)f[i][j]=1061109567;for(int j=g[l].up;j<=m;j++)f[i][j]=1061109567;bool flag=1;for(int j=1;j<=m;j++)if(f[i][j]<1061109567){flag=0;break;}if(flag){printf("0\n%d",l-1);return 0;}l++;}for(int j=1;j<=m;j++)f[i+1][upa]=min(min(f[i][j],f[i+1][j])+1,f[i+1][upa]);for(int j=down[i+1]+1;j<=m;j++)f[i+1][j-down[i+1]]=min(f[i+1][j-down[i+1]],f[i][j]);}for(int j=1;j<=m;j++)mins=min(mins,f[n][j]);printf("1\n%d",mins); }總結
以上是生活随笔為你收集整理的P1941-飞扬的小鸟【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2014台式电脑配置清单(2014台式电
- 下一篇: 如何查看电脑显卡配置(看电脑显卡配置)