演算法複習——區間dp

來源:互聯網
上載者:User

標籤: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.