標籤:div out color i++ ems algo 問題 head namespace
感覺對區間dp也不好說些什麼直接照搬講義了2333
例題:1.引水入城(洛穀1514)
這道題先開始看不出來到底和區間dp有什麼卵關係····
首先肯定是bfs暴力判一判可以覆蓋到哪些城市····無解直接輸出···有解得話就要想想了····
這道題關鍵是要發現··如果一個蓄水池所在城市可以覆蓋到一些沙漠城市···那麼這些沙漠城市肯定是一段····不然假設有一個城市是斷開的而兩邊都被同一個蓄水池流出的水覆蓋,這個城市四周的城市都肯定比它矮···(不理解舉個反例吧···反正我舉不出來)···然後就可以找到每一個蓄水池它對應的可以覆蓋的區間···轉化成一個關於線段覆蓋的區間dp問題·····即可求解(dp方程看代碼吧)
另外這道題bfs時注意是入隊時打標記不然會爆···另外判條件時先判越界沒有···
代碼:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<cctype>#include<cstring>#include<string>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;const int N=1005;const int gox[4]={1,0,-1,0};const int goy[4]={0,1,0,-1};struct node{ int x,y;}que[N*N];struct node1{ int l,r;}g[N];int map[N][N],n,m,tail,head,f[N];bool visit[N][N];inline int R(){ char c;int f=0; for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()); for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f;}inline void bfs(){ head=1,tail=0; for(int i=1;i<=m;i++) { que[++tail].x=1;que[tail].y=i; visit[que[head].x][que[head].y]=true; } for(;head<=tail;head++) { for(int i=0;i<=3;i++) { visit[que[head].x][que[head].y]=true; int vx=que[head].x+gox[i];int vy=que[head].y+goy[i]; if(vx<1||vx>n||vy<1||vy>m||visit[vx][vy]||map[vx][vy]>=map[que[head].x][que[head].y]) continue; node temp; temp.x=vx,temp.y=vy;que[++tail]=temp; visit[temp.x][temp.y]=true; } }}inline void dfs(int x,int y,int u){ visit[x][y]=true; if(x==n) g[u].l=min(g[u].l,y),g[u].r=max(g[u].r,y); for(int i=0;i<=3;i++) { int vx=x+gox[i];int vy=y+goy[i]; if(visit[vx][vy]||vx<1||vx>n||vy<1||vy>m||map[vx][vy]>=map[x][y]) continue; dfs(vx,vy,u); }}int main(){ //("a.in","r",stdin); memset(f,inf,sizeof(f)); n=R(),m=R(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) map[i][j]=R(); bfs(); int temp=0; for(int i=1;i<=m;i++) if(visit[n][i]==true) temp++; if(temp!=m) { cout<<"0"<<endl; cout<<m-temp<<endl; return 0; } for(int i=1;i<=m;i++) { memset(visit,false,sizeof(visit)); g[i].l=m+1;g[i].r=0; dfs(1,i,i); } f[0]=0; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) if(g[j].l<=i&&g[j].r>=i) f[i]=min(f[i],f[g[j].l-1]+1); cout<<"1"<<endl; cout<<f[m]<<endl; return 0;}
演算法複習——區間dp