CodeForces 295C - Greg and Friends BFS找最短路径

来源:互联网 发布:行书笔顺演示软件 编辑:程序博客网 时间:2024/06/02 01:44

   由于每个人只有两种重量50kg和100kg...并且人数只有至多50个...用dis[50][50][2]表示状态...dis[x][y][0]表示在原岸有x个50kg..y个100kg...dis[x][y][1]在目标岸有x个50kg..y个100kg...

    对于当前的一个状态...枚举多少个50kg..多少个100kg坐船去对岸(当然要船承受得了)....而对面的的状态可以推出来...

    如当前状态是 dis[x][y][0]...总人数中有50kg的人n1...有100kg的人n2...那么对岸的情况对应的是dis[n1-x][n2-y][1]...若是有a个50kg的和b个100kg的过河..那么对岸对应的状态是dis[n1-x+a][n2-y+b][1]...

    注意的是题目要求..每次过河的人至少一个..


Program:

#include<iostream>#include<stack>#include<queue>#include<stdio.h>#include<algorithm>#include<string.h>#include<cmath>#define ll long long#define oo 1000000007#define MAXN 55using namespace std;struct node{      int n1,n2,tp;}h,p;ll dis[MAXN][MAXN][2],way[MAXN][MAXN][2],C[MAXN][MAXN];queue<node> myqueue;int n,k;void PreWork(){      int i,j;      for (i=0;i<=50;i++) C[i][0]=1;      for (i=1;i<=50;i++)         for (j=1;j<=50;j++)            C[i][j]=(C[i-1][j-1]+C[i-1][j])%oo;      return;}int main(){        int i,j;      PreWork();         while (~scanf("%d%d",&n,&k))      {                 int n1,n2;              n1=n2=0;              for (i=1;i<=n;i++)              {                     int x;                     scanf("%d",&x);                     if (x==50) n1++; else n2++;              }              memset(dis,0,sizeof(dis));              memset(way,0,sizeof(way));              dis[n1][n2][0]=1;              way[n1][n2][0]=1;              h.n1=n1,h.n2=n2,h.tp=0;              while (!myqueue.empty()) myqueue.pop();              myqueue.push(h);              while (!myqueue.empty())              {                     h=myqueue.front();                     myqueue.pop();                     for (j=0;j<=h.n2;j++)                     {                           if (j*100>k) break;                           for (i=0;i<=h.n1;i++)                           {                                  if (!j && !i) continue;                                  if (i*50+j*100>k) break;                                   p.n1=n1-h.n1+i,p.n2=n2-h.n2+j,p.tp=1-h.tp;                                   if (!dis[p.n1][p.n2][p.tp])                                  {                                         myqueue.push(p);                                         dis[p.n1][p.n2][p.tp]=dis[h.n1][h.n2][h.tp]+1;                                  }                                   if (dis[p.n1][p.n2][p.tp]==dis[h.n1][h.n2][h.tp]+1)                                  {                                         ll t;                                         t=(C[h.n1][i]*C[h.n2][j])%oo;                                         t=(t*way[h.n1][h.n2][h.tp])%oo;                                         way[p.n1][p.n2][p.tp]=(way[p.n1][p.n2][p.tp]+t)%oo;                                  }                           }                     }                                   }              printf("%I64d\n%I64d\n",dis[n1][n2][1]-1,way[n1][n2][1]);      }            return 0;}