舞蹈家怀特先生

codevs 3049 舞蹈家怀特先生

http://codevs.cn/problem/3049/

难度等级:黄金

题目描述 Description

怀特先生是一个大胖子。他很喜欢玩跳舞机(Dance Dance Revolution, DDR),甚至希望有一天人家会脚踏“舞蹈家怀特先生”。可惜现在他的动作根本不能称作是在跳舞,尽管每次他都十分投入的表演。这也难怪,有他这样的体型,玩跳舞机是相当费劲的。因此,他希望写一个程序来安排舞步,让他跳起来轻松一些,至少不要每次都汗流浃背。
  DDR的主要内容是用脚来踩踏板。踏板有四个方向的箭头,用1 (Up)、2 (Left)、3 (Down)、4 (Right)来代表,中间位置由0来代表。每首歌曲有一个箭头序列,游戏者必须按照或这个序列一次用某一只脚踩相应的踏板。在任何时候,两只脚都不能在同一踏板上,但可以同时待在中心位置0。
  每一个时刻,它必须移动而且只能移动他的一只脚去踩相应的箭头,而另一只脚不许移动。跳完一首曲子之后,怀特先生会计算他所消耗的体力。从中心移动到任何一个箭头耗费2单位体力,从任何一个箭头移动到相邻箭头耗费3单位体力,移动到相对的箭头(1和3相对,2和4相对)耗费4单位体力,而留在原地再踩一下只需要1单位。怀特先生应该怎样移动他的双脚(即,对于每个箭头,选一只脚去踩它),才能用最少的体力完成一首给定的舞曲呢?
  例如,对于箭头序列Left (2), Left (2), Up (1), Right (4),他应该分别用左、左、右、右脚去踩,总的体力耗费为2+1+2+3=8单位。

输入描述 Input Description

第一行N,表示有N个时刻 1<=N<=10000
第二到n+1行,每行一个数,表示需要踩得版

输出描述 Output Description

一个数,最小消耗体力

样例输入 Sample Input

2

1

1

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

n<=10000

f[i][l][r]表示踩了i步,第i步左脚踩在l,右脚踩在r的最小消耗体力

初始化:f极大值

特殊处理:第1步规定左脚踩,左脚踩到直到出现与第一个不同的箭头,换右脚踩第一步

状态转移:设第i步踩在x

f[i][l][r]=min(f[i-1][x][r]+move[l][x])

f[i][l][r]=min(f[i-1][l][r]+move[r][x])

第一次代码,没有预处理move数组,代码冗长,判断移动消耗多少体力时老出错

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,f[10001][5][5],y,ans=50000;
int work(int i,int l,int r,int self,int left,int right,int now_l,int now_r,int p)
{
    if(p==self) f[i][now_l][now_r]=min(f[i][now_l][now_r],f[i-1][l][r]+1);
    else if(p==left||p==right)  f[i][now_l][now_r]=min(f[i][now_l][now_r],f[i-1][l][r]+3);
    else f[i][now_l][now_r]=min(f[i][now_l][now_r],f[i-1][l][r]+4);
}
int main()
{
    scanf("%d",&n);
    memset(f,127,sizeof(f));
    f[0][0][0]=0;
    int a;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&y);
        if(i==1)
        {
            f[1][y][0]=2,a=y;
            continue;
        }
        if(a)
        {
            if(y==a)
             f[i][y][0]=f[i-1][y][0]+1;
            else
             {
                 f[i][a][y]=f[i-1][a][0]+2;
                 a=0;
             }
             continue;
        }
        for(int l=1;l<=4;l++)
         for(int r=1;r<=4;r++)
         {
             if(f[i-1][l][r]>40000) continue;
             if(y==1)  work(i,l,r,1,2,4,y,r,l);
             else if(y==2) work(i,l,r,2,1,3,y,r,l);
             else if(y==3) work(i,l,r,3,2,4,y,r,l);
             else  work(i,l,r,4,1,3,y,r,l);
         }
        for(int l=1;l<=4;l++)
         for(int r=1;r<=4;r++)
         {
             if(f[i-1][l][r]>40000) continue;
             if(y==1)  work(i,l,r,1,2,4,l,y,r);
             else if(y==2) work(i,l,r,2,1,3,l,y,r);
             else if(y==3) work(i,l,r,3,2,4,l,y,r);
             else  work(i,l,r,4,1,3,l,y,r);
         }
    }
    for(int i=0;i<=4;i++)
     for(int j=0;j<=4;j++)
      ans=min(ans,f[n][i][j]);
    printf("%d",ans);
}

第二次代码,预处理move数组,简单方便

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,f[10001][5][5],y,ans=50000;
int move[5][5]={{0,2,2,2,2},{0,1,3,4,3},{0,3,1,3,4},{0,4,3,1,3},{0,3,4,3,1}};
int main()
{
    scanf("%d",&n);
    memset(f,127,sizeof(f));
    f[0][0][0]=0;
    int a;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&y);
        if(i==1)
        {
            f[1][y][0]=2,a=y;
            continue;
        }
        if(a)
        {
            if(y==a)
             f[i][y][0]=f[i-1][y][0]+1;
            else
             {
                 f[i][a][y]=f[i-1][a][0]+2;
                 a=0;
             }
             continue;
        }
        for(int l=1;l<=4;l++)
         for(int r=1;r<=4;r++)
         {
             if(f[i-1][l][r]>40000) continue;
            f[i][y][r]=min(f[i][y][r],f[i-1][l][r]+move[l][y]);
         }
        for(int l=1;l<=4;l++)
         for(int r=1;r<=4;r++)
         {
             if(f[i-1][l][r]>40000) continue;
             f[i][l][y]=min(f[i][l][y],f[i-1][l][r]+move[r][y]);
         }
    }
    for(int i=0;i<=4;i++)
     for(int j=0;j<=4;j++)
      ans=min(ans,f[n][i][j]);
    printf("%d",ans);
}
时间: 2024-10-16 11:09:00

舞蹈家怀特先生的相关文章

3049 舞蹈家怀特先生

3049 舞蹈家怀特先生 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 怀特先生是一个大胖子.他很喜欢玩跳舞机(Dance Dance Revolution, DDR),甚至希望有一天人家会脚踏“舞蹈家怀特先生”.可惜现在他的动作根本不能称作是在跳舞,尽管每次他都十分投入的表演.这也难怪,有他这样的体型,玩跳舞机是相当费劲的.因此,他希望写一个程序来安排舞步,让他跳起来轻松一些,至少不要每次都汗流浃背. DDR的主要内容是用脚来

动态规划 舞蹈家怀特

3049 舞蹈家怀特先生 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 怀特先生是一个大胖子.他很喜欢玩跳舞机(Dance Dance Revolution, DDR),甚至希望有一天人家会脚踏"舞蹈家怀特先生".可惜现在他的动作根本不能称作是在跳舞,尽管每次他都十分投入的表演.这也难怪,有他这样的体型,玩跳舞机是相当费劲的.因此,他希望写一个程序来安排舞步,让他跳起来轻松一些,至少不要每次都汗流浃背. DDR的

CODEVS 3049 舞蹈家怀特先生

根据题目描述,只有一开始会站在0这个格子上,以后不会向这个格子移动 假设f[i][j][k] 为 当前时间i,两只脚分别在j,k两个格子上的最小体力花费 第i个时间的状态为f[i][a[i]][k]或者f[i][j][a[i]],即有一只脚在指定格子上,所以分两种情况枚举 转移方程 f[i][j][a[i]] = min(f[i][j][a[i]],f[i-1][j][k]+move(a[i],k)); f[i][a[i]][k] = min(f[i][a[i]][k],f[i-1][j][k]

经典的动态规划

有一个动态规划100例...看到机房里shenben的复习资料...加上垃圾的dp....整理一下. 一.资源分配问题 tyvj 1203 机器分配 题目大意:有m个设备,n个公司,v[i][j]表示第i个公司分j个设备的贡献值.怎样分配使贡献值的和最大? 状态:前i个公司分j个设备. f[i][j]表示前i个公司分j个设备,枚举第i个公司分k个设备. 状态转移方程:f[i][j]=max{f[i-1][j-k]+v[i][k]} 这个还挺简单的. 洛谷P2736 "破锣摇滚"乐队 R

制霸禁区的男人 防守大闸怀特塞德评测

2016年6月14日星期二,热火中锋“白边”怀特塞德迎来自己的27岁生日.曾经打过CBA的他如今已经成为了NBA的一流中锋,成为热火的防守大闸,这个赛季更是打出了自己的身价,打破了多项纪录的他更是跻身一流内线. 说起白边,大家首先想到的肯定是他的致命的盖帽.有多少人因为这记抓冒而爱上这个大男孩? 游戏中的白边也是现役屈指可数的可攻可守的内线.接下来我们就去全面解析这位来自热火的大中锋吧. 一,球员属性分析: 白边特长为防守五颗星,有4项数据达到190以上. 球员模型: 1, 身体素质方面: A,

回收IC芯片,回收美国怀特WEDC/EDI/WHITE存储器军用科研芯片

13689523991QQ:805657701高价回收美国怀特WEDC/EDI/WHITE存储器军用科研芯片,宽温储存芯片ELISRA,LATTICE,NSC,XILINX,ALTERA,INTERSIL,AVAGO,HITTITE,ATMEL,CYPRESS,APMHENOL,e2V,QP,SEMI,COOPER,BUSSMANN,M/ACOMACTEL,ADI,MAXIAM,TI/BB,FREESCALE,WEDC,ELISRA,LATTICE,NSC,XILINX,ALTERA,INTER

Alfred North Whilehead阿尔弗雷德&#183;诺尔司&#183;怀特海

Civilization advances by extending the number of important operations which we can perform without thinking about them.   Alfred North Whilehead An Introduction Mathematics, 1911. 一. Civilization /sivilizei??n/ BRIT also civilisation    英国英语为 civilis

No parking

原文 Jasper White is one of those rare people who believes in ancient myths. He has just bought a new house in the city, but ever since he moved in, he has had trouble with cars and their owners. When he returns home at night, he always finds that some

世界主要城市经纬度

城市英文名 城市中文名 所属国家 纬度 经度 Abidjan 阿比让 科特迪瓦 北纬:5°19' 东经:4°01' Abu Dhabi 阿布扎比 阿联酋 北纬:24°27' 东经:54°23' Abuja 阿布贾 尼日利亚 北纬:9°12' 东经:7°11' Acapulco 阿卡普尔科 墨西哥 北纬:16°51' 西经:99°56' Accra 阿克拉 加纳 北纬:5°33' 东经:0°15' Adak 艾达克岛 美国 北纬:51°52' 东经:176°39' Adamstown 亚当斯敦 英