Bzoj 1616: [Usaco2008 Mar]Cow Travelling遊蕩的奶牛

奶牛們在被劃分成N行M列(2 <= N <= 100; 2 <= M <= 100)的草地上游走,試圖找到整塊草地中最美味的牧草。Farmer John在某個時刻看見貝茜在位置 (R1, C1),恰好T (0 < T <= 15)秒後,FJ又在位置(R2, C2)與貝茜撞了正着。 FJ並不知道在這T秒內貝茜是否曾經到過(R2, C2),他能確定的只是,現在貝茜在那裏。 設S爲奶牛在T秒內從(R1, C1)走到(R2, C2)所能選擇的路徑總數,FJ希望有一個程序來幫他計算這個值。每一秒內,奶牛會水平或垂直地移動1單位距離(奶牛總是在移動,不會在某秒內停在它上一 秒所在的點)。草地上的某些地方有樹,自然,奶牛不能走到樹所在的位置,也不會走出草地。 現在你拿到了一張整塊草地的地形圖,其中’.’表示平坦的草地,’*’表示擋路的樹。你的任務是計算出,一頭在T秒內從(R1, C1)移動到(R2, C2)的奶牛可能經過的路徑有哪些。

雙向廣搜
從起點出發走T/2步,記錄每個格子到達次數a[i][j]
從終點出發走T-T/2步,記錄每個格子到達次數b[i][j]
所有格子的a[i][j]*b[i][j]就是答案
複雜度4^(T/2)+n*m
此題如果T更大,可以用dp解決,做到O(n*m*T)或O((n*m)^3*logT)

#include<iostream>
using namespace std;
int n,t,m;
int hz[5]={0,0,0,1,-1};
int zz[5]={0,1,-1,0,0};
int a[101][101],b[101][101];char tmp[101][101];
int dfs(int bs,int h,int z,int s[101][101],int tt)
{  if (bs>tt)
   {  s[h][z]++;
      return 0;
   }
   for (int i=1;i<=4;++i)
   {  if (h+hz[i]>=1&&h+hz[i]<=n&&z+zz[i]>=1&&z+zz[i]<=m)
       if (tmp[h+hz[i]][z+zz[i]]!='*')
      {  
               dfs(bs+1,h+hz[i],z+zz[i],s,tt);
      }
   }
}
int main()
{ 
   int x1,y1,x2,y2;
   cin>>n>>m>>t;
   for (int i=1;i<=n;++i)
     for (int j=1;j<=m;++j)
       cin>>tmp[i][j];
   cin>>x1>>y1>>x2>>y2;
    int t1=t/2;
    int t2=t-t1;
   dfs(1,x1,y1,a,t1);
   dfs(1,x2,y2,b,t2);
   int ans=0;
   for (int i=1;i<=n;++i)
     for (int j=1;j<=m;++j)
         ans+=a[i][j]*b[i][j];
   cout<<ans;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章