HDOJ4433-locker,2012ACM天津站C题,DP

来源:互联网 发布:中国少数民族政策知乎 编辑:程序博客网 时间:2024/04/27 22:14

被yobobobo的五十行代码给鄙视了!~写挫鸟~~

dp[i][j]表示前i个数字中前i-2个数字已经调换好了,第i-1个数字x和第i个数字y满足x*10+y=j对应状态的最小操作数,代码如下:

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int NN=1010;int r1[NN][NN],r2[NN][NN],r3[NN][NN];int min3(int x,int y,int z){    int ret=x;    if (y<ret) ret=y;    if (z<ret) ret=z;    return ret;}int fuck1(int x,int y)//一位数转变{    if (r1[x][y]!=-1) return r1[x][y];    if (x==y) return r1[x][y]=0;    if (x>y) return r1[x][y]=r1[y][x]=min(x-y,10+y-x);    else     return r1[y][x]=r2[x][y]=min(y-x,10+x-y);}int fuck2(int x,int y)//两位数转变{    if (r2[x][y]!=-1) return r2[x][y];    if (x==y) return r2[x][y]=0;    int a,b,tmp;    int ret=fuck1(x/10,y/10)+fuck1(x%10,y%10);    a=x;    for (int i=1; i<=5; i++)    {        b=0;        for (int k=1; k<=10; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k;        a=b;        tmp=fuck1(a/10,y/10)+fuck1(a%10,y%10);        if (tmp+i<ret) ret=tmp+i;    }    for (int i=4; i>=1; i--)    {        b=0;        for (int k=1; k<=10; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k;        a=b;        tmp=fuck1(a/10,y/10)+fuck1(a%10,y%10);        if (tmp+i<ret) ret=tmp+i;    }    return r2[x][y]=r2[y][x]=ret;}int fuck3(int x,int y)//三位一起转变{    if (r3[x][y]!=-1) return r3[x][y];    if (x==y) return r3[x][y]=0;    int a,b,tmp;    int ret=min(fuck1(x/100,y/100)+fuck2(x%100,y%100),fuck2(x/10,y/10)+fuck1(x%10,y%10));    a=x;    for (int i=1; i<=5; i++)    {        b=0;        for (int k=1; k<=100; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k;        a=b;        tmp=min(fuck1(a/100,y/100)+fuck2(a%100,y%100),fuck2(a/10,y/10)+fuck1(a%10,y%10));        if (tmp+i<ret) ret=tmp+i;    }    for (int i=4; i>=1; i--)    {        b=0;        for (int k=1; k<=100; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k;        a=b;        tmp=min(fuck1(a/100,y/100)+fuck2(a%100,y%100),fuck2(a/10,y/10)+fuck1(a%10,y%10));        if (tmp+i<ret) ret=tmp+i;    }    return r3[x][y]=r3[y][x]=ret;}int n,s1[NN],s2[NN],s3[NN],t1[NN],t2[NN],t3[NN],dp[NN][NN];char s[NN],t[NN];int main(){    memset(r1,-1,sizeof(r1));    memset(r2,-1,sizeof(r2));    memset(r3,-1,sizeof(r3));    for (int i=0; i<=9;   i++) for (int j=i; j<=9;   j++)  r1[i][j]=r1[j][i]=fuck1(i,j);    for (int i=0; i<=99;  i++) for (int j=i; j<=99;  j++)  r2[i][j]=r2[j][i]=fuck2(i,j);    for (int i=0; i<=999; i++) for (int j=i; j<=999; j++)  r3[i][j]=r3[j][i]=fuck3(i,j);    while (scanf("%s%s",s,t)!=EOF)    {        n=strlen(s);        s1[0]=s2[0]=s3[0]=s[0]-'0';        s1[1]=s[1]-'0';        s2[1]=s3[1]=(s[0]-'0')*10+s[1]-'0';        for (int i=2; i<n; i++)        {            s1[i]=s[i]-'0';            s2[i]=(s[i-1]-'0')*10+s1[i];            s3[i]=(s[i-2]-'0')*100+s2[i];        }        t1[0]=t2[0]=t3[0]=t[0]-'0';        t1[1]=t[1]-'0';        t2[1]=t3[1]=(t[0]-'0')*10+t[1]-'0';        for (int i=2; i<n; i++)        {            t1[i]=t[i]-'0';            t2[i]=(t[i-1]-'0')*10+t1[i];            t3[i]=(t[i-2]-'0')*100+t2[i];        }        if (n==1) { printf("%d\n",r1[s1[0]][t1[0]]); continue; }        if (n==2) { printf("%d\n",r2[s2[1]][t2[1]]); continue; }        if (n==3) { printf("%d\n",r3[s3[2]][t3[2]]); continue; }        for (int i=0; i<=9;  i++) dp[0][i]=r1[s1[0]][i];        for (int i=0; i<=99; i++) dp[1][i]=r2[s2[1]][i];        for (int i=0; i<=99; i++) dp[2][i]=r3[s3[2]][t1[0]*100+i];        for (int i=3; i<n; i++)          for (int j=0; j<=99; j++)          {              dp[i][j]=min3(dp[i-1][t1[i-2]*10+j/10]+r1[s1[i]][j%10],                            dp[i-2][t2[i-2]]        +r2[s2[i]][j],                            dp[i-3][t2[i-3]]        +r3[s3[i]][t1[i-2]*100+j]);              for (int k=0; k<=9; k++)              {                  dp[i][j]=min(dp[i][j],dp[i-1][t1[i-2]*10+k]+r2[k*10+s1[i]][j]);                  dp[i][j]=min(dp[i][j],dp[i-2][t1[i-3]*10+k]+r3[k*100+s2[i]][t1[i-2]*100+j]);              }              for (int k=0; k<=99; k++)              {                  dp[i][j]=min(dp[i][j],dp[i-1][k]+r3[k*10+s1[i]][t1[i-2]*100+j]);              }          }        printf("%d\n",dp[n-1][t2[n-1]]);    }    return 0;}