• HDU 4433 locker(SPFA+DP)


    题目链接

    去年区域赛的题目,早就看过题目了,又是过了好久了。。。

    这题状态转移,一看就知道应该是 线性的那种,不过细节真的不好处理,一直没想出怎么搞,期间也看过题解,好像没太看懂。。。

    dp[i][j]表示前i位相同,i之后两位为j的最小转动次数。

    例如dp[i][x*10+y]  i+3位 为z(初始数字),x y z 转化为 ax ay az,ax肯定是第二个串的第i位,后两位随便就可以。

    只要 预处理 xyz 转化为axayaz的情况,就行了。dp[0]初始化,100位直接Floyd,其他的1000位的预处理,用spfa搞的。

    预处理写的很长。。

      1 #include <cstring>
      2 #include <cstdio>
      3 #include <string>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 using namespace std;
      9 #define INF 10000000
     10 char s1[1200],s2[1200];
     11 int dp[1010][110];
     12 int mp[1010][1010];
     13 int dis[1010];
     14 int in[1010];
     15 int p[101][101];
     16 int n1[1010],n2[1010];
     17 int a[12] = {1,0,0,1,0,1,-1,0,0,-1,0,-1};
     18 int b[12] = {0,1,0,1,1,1,0,-1,0,-1,-1,-1};
     19 int c[12] = {0,0,1,0,1,1,0,0,-1,0,-1,-1};
     20 void spfa(int key)
     21 {
     22     int x,y,z,i,ax,ay,az,u,v;
     23     queue <int> que;
     24     for(i = 0;i < 1000;i ++)
     25     {
     26         dis[i] = INF;
     27         in[i] = 0;
     28     }
     29     in[key] = 1;
     30     dis[key] = 0;
     31     que.push(key);
     32     while(!que.empty())
     33     {
     34         u = que.front();
     35         in[u] = 0;
     36         que.pop();
     37         x = (u/100)%10;
     38         y = (u/10)%10;
     39         z = u%10;
     40         for(i = 0;i < 12;i ++)
     41         {
     42             ax = (x+a[i]+10)%10;
     43             ay = (y+b[i]+10)%10;
     44             az = (z+c[i]+10)%10;
     45             v = ax*100+ay*10+az;
     46             if(dis[v] > dis[u] + 1)
     47             {
     48                 if(!in[v])
     49                 {
     50                     in[v] = 1;
     51                     que.push(v);
     52                 }
     53                 dis[v] = dis[u] + 1;
     54             }
     55         }
     56     }
     57     for(i = 0;i < 1000;i ++)
     58     mp[key][i] = dis[i];
     59     return ;
     60 }
     61 int main()
     62 {
     63     int i,j,len,x,y,z,k,temp;
     64     for(i = 0;i < 100;i ++)
     65     {
     66         for(j = 0;j < 100;j ++)
     67         p[i][j] = INF;
     68         p[i][i] = 0;
     69     }
     70     for(i = 0;i < 100;i ++)
     71     {
     72         x = (i/10)%10;
     73         y = i%10;
     74         p[x][(y+1)%10] = 1;
     75         p[(y+1)%10][x] = 1;
     76         p[(x+1)%10][y] = 1;
     77         p[y][(x+1)%10] = 1;
     78         p[(x+1)%10][(y+1)%10] = 1;
     79         p[(y+1)%10][(x+1)%10] = 1;
     80     }
     81     for(i = 0;i < 100;i ++)
     82     {
     83         for(j = 0;j < 100;j ++)
     84         {
     85             for(k = 0;k < 100;k ++)
     86             {
     87                 if(p[j][k] > p[j][i] + p[i][k])
     88                 p[j][k] = p[j][i] + p[i][k];
     89             }
     90         }
     91     }
     92     for(i = 0;i < 1000;i ++)
     93     {
     94         spfa(i);
     95     }
     96     while(scanf("%s%s",s1,s2)!=EOF)
     97     {
     98         len = strlen(s1);
     99         for(i = 1;i <= len;i ++)
    100         {
    101             n1[i] = s1[i-1] - '0';
    102             n2[i] = s2[i-1] - '0';
    103         }
    104         for(i = 0;i <= len;i ++)
    105         {
    106             for(j = 0;j < 100;j ++)
    107             dp[i][j] = INF;
    108         }
    109         n1[len+1] = n2[len+1] = 0;
    110         n1[len+2] = n2[len+2] = 0;
    111         temp = n1[1] * 10 + n1[2];
    112         for(i = 0;i < 100;i ++)
    113         {
    114             dp[0][i] = p[temp][i];
    115         }
    116         for(i = 0;i < len;i ++)
    117         {
    118             z = n1[i+3];
    119             for(j = 0;j < 100;j ++)
    120             {
    121                 x = (j/10)%10;
    122                 y = j%10;
    123                 for(k = 0;k < 100;k ++)
    124                 {
    125                     if(dp[i+1][k] > dp[i][j] + mp[j*10+z][n2[i+1]*100+k])
    126                     dp[i+1][k] = dp[i][j] + mp[j*10+z][n2[i+1]*100+k];
    127                 }
    128             }
    129         }
    130         printf("%d
    ",dp[len][0]);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    设计模式学习笔记之设计原则
    设计模式学习笔记之生成器模式
    设计模式学习笔记之适配器模式、外观模式
    java中的日期类型之间转换
    JS刷新当前页面的几种方法总结
    Java_枚举
    动态规划详解_2
    Java算法-动态规划详解
    Java经典算法题_2
    Java算法
  • 原文地址:https://www.cnblogs.com/naix-x/p/3296178.html
Copyright © 2020-2023  润新知