codefroces 2B The least round way

来源:互联网 发布:linux查看二进制文件 编辑:程序博客网 时间:2024/04/26 11:54

题意:一个矩阵中写满数字,从左上都到左下,每次只能向下方和右方走,每次经过一点,就乘以那个点上的数。求一条路径,是最终结果末尾的零最少。

做法:一般的路径DP。只要DP求出两条路径,一条获得的2最少,一条5最少,然后比较去其中值最小的一条。可惜,一开始写了个不必要的优化,时间加长,还容易错,以后这种没必要的事情还是别做了

#include <cstdio>#include<cstring>#define LMT 1000004//0°¡Áã°¡int two[LMT],five[LMT],dd[2][LMT],dp2[LMT],dp5[LMT],sign;char stack[LMT];void work(int x,int xi){    if(!x)    {        sign=xi+1;        two[xi]+=10;        five[xi]+=10;        return;    }    while(x%5==0)    {        five[xi]++;        x/=5;    }    while(x%2==0)    {        two[xi]++;        x/=2;    }}int main(void){    int x,n,i,j,ans;    scanf("%d",&n);    for(i=0;i<n;i++)      for(j=0;j<n;j++)      {          scanf("%d",&x);          work(x,i*n+j);      }      memset(dp2,-1,sizeof(dp2));      memset(dp5,-1,sizeof(dp5));      dp2[0]=two[0];      dp5[0]=five[0];      for(x=1;x<n*n;x++)      {          i=x/n;          j=x%n;          if(i&&(dp2[x]>dp2[(i-1)*n+j]+two[x]||dp2[x]==-1))          {              dd[1][x]=1;              dp2[x]=dp2[(i-1)*n+j]+two[x];          }          if(j&&(dp2[x]>dp2[i*n+j-1]+two[x]||dp2[x]==-1))          {             dp2[x]=dp2[i*n+j-1]+two[x];             dd[1][x]=0;          }          if(i&&(dp5[x]>dp5[(i-1)*n+j]+five[x]||dp5[x]==-1))          {              dd[0][x]=1;              dp5[x]=dp5[(i-1)*n+j]+five[x];          }          if(j&&(dp5[x]>dp5[i*n+j-1]+five[x]||dp5[x]==-1))          {            dp5[x]=dp5[i*n+j-1]+five[x];            dd[0][x]=0;          }      }      int tag,top=0;      x=n*n-1;      if(dp2[x]>dp5[x])      {          tag=0;          ans=dp5[x];      }      else      {          tag=1;          ans=dp2[x];      }      if(ans>1&&sign)      {          ans=1;          sign--;          i=sign/n;j=sign%n;          int ii=n-1,jj=n-1;          while(jj!=j)          {              stack[top++]='R';              jj--;          }          while(ii)          {              stack[top++]='D';              ii--;          }          while(jj)          {              stack[top++]='R';              jj--;          }      }      else      {           while(x)         {             i=x/n;             j=x%n;             if(dd[tag][x])            {              x=(i-1)*n+j;              stack[top++]='D';            }             else            {              x=i*n+j-1;              stack[top++]='R';            }          }      }      printf("%d\n",ans);      while(top>0)printf("%c",stack[--top]);        printf("\n");      return 0;}