• SOJ 2818_QQ音速


    【题意】两只手,一次只能用一只手按一个键子(0,1,2,3),给出从i键到j键所需的消耗的体力,求依次按下一系列键子所需最小体力。

    【分析】

    法一:开一个三维数组,分别记录移动到位置及左右手按的键子。

    状态转移方程;

     v[k][i][j]=min(v[k-1][c[k-1]-'0'][j]+w[c[k-1]-'0'][i],v[k-1][i][c[k-1]-'0']+w[c[k-1]-'0'][j]);其中k取遍0.1.2.3

    【代码】

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1000050;
    int v[maxn][4][4];
    int w[4][4]={{0,1,2,2},{1,0,1,1},{2,1,0,2},{2,1,2,0}};
    int Min;
    char c[maxn];
    const int INF=0x3fffffff;
    int main (void)
    {
        while(scanf("%s",c)==1)
        {
            Min=INF;
            int len=strlen(c);
            memset(v,10,sizeof(v));
            for(int i=0;i<4;i++)
                 for(int j=0;j<4;j++)
                     v[0][i][j]=w[3][j]+w[2][i];
    
    
             for(int k=1;k<len;k++)
            {
                for(int i=0;i<4;i++)
                {
                    for(int j=0;j<4;j++)
                        v[k][i][j]=min(v[k-1][c[k-1]-'0'][j]+w[c[k-1]-'0'][i],v[k-1][i][c[k-1]-'0']+w[c[k-1]-'0'][j]);
                }
            }
          for(int i=0;i<4;i++)
            {
                Min=min(v[len-1][i][c[len-1]-'0'],Min);
                Min=min(v[len-1][c[len-1]-'0'][i],Min);
            }
            printf("%d
    ",Min);
        }
        return 0;
    }
    

    法二:开一个二维数组,分别记录移动的次数及对于某一只手来说该次移动所按的键子(注意边界

    状态转移方程:

    对于j取遍0,1,2,3

    当j==c[i-1]-'0'时
                        for(int k=0;k<4;k++)
                           v[i][j]=min(v[i][j],v[i-1][k]+w[k][c[i]-'0']);(j==c[i-1]-'0'
    当j!=c[i-1]-'0时     v[i][j]=v[i-1][j]+w[c[i-1]-'0'][c[i]-'0'];

    【代码】

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1000050;
    int v[maxn][4];
    int w[4][4]={{0,1,2,2},{1,0,1,1},{2,1,0,2},{2,1,2,0}};
    int Min,len;
    char c[maxn];
    const int INF=0x3fffffff;
    int main (void)
    {
        while(scanf("%s",c)==1)
        {
            Min=INF;
            len=strlen(c);
            for(int i=0;i<maxn;i++)
                 for(int j=0;j<4;j++)
                     v[i][j]=INF;
            v[0][2]=w[3][c[0]-'0'];
            v[0][3]=w[2][c[0]-'0'];
            for(int i=1;i<len;i++)
            {
                for(int j=0;j<4;j++)
                {
                   if(j==c[i-1]-'0')
                    {
                        for(int k=0;k<4;k++)
                           v[i][j]=min(v[i][j],v[i-1][k]+w[k][c[i]-'0']);
                    }
                   else
                        v[i][j]=v[i-1][j]+w[c[i-1]-'0'][c[i]-'0'];
                }
            }
            for(int i=0;i<4;i++)
                Min=min(v[len-1][i],Min);
            printf("%d
    ",Min);
        }
        return 0;
    }
    


  • 相关阅读:
    面向对象基础小结
    异常应用场景
    集合应用场景1:迭代器
    集合应用场景2——数据结构
    华为ce交换机 Bridge-Domain NVE
    linux 内核内置模块
    linux bridge 转发 ip
    iptables nat&conntrack
    loopback
    配置集中式网关部署方式的VXLAN示例(静态方式)
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758873.html
Copyright © 2020-2023  润新知