首页 > 代码库 > 「Poetize5」GF弹钢琴

「Poetize5」GF弹钢琴

描述 Description

现在PianoEater有一架有52个白键和 36个黑键的钢琴,并且他要弹奏的曲子只需要按白键。在同一时刻,他只用弹奏一个音符。如果这个音符不移动大拇指就可以按到,那么他不需要耗费体力;否则 他需要花费sqrt(x)(下取整)的体力来移动手的位置(也就是移动大拇指的位置)。其中x代表移动前后大拇指的位置之差的绝对值。
现在有一首由N个音符组成的乐曲,每个音符用0~51之间的一个整数表示,分别对应了52个白键。0是最左边的键,51是最右边的键。PianoEater想知道他弹完这首曲子最少需要耗费多少体力。

题解:

题目说了好多废话。。。

理解了题意之后就是一个无脑DP

f[i][j][k]表示第 i 次左手大拇指在j,右手大拇指在k,然后暴力转移就行了,注意转移的范围。

代码:

 1 #include<cstdio> 2  3 #include<cstdlib> 4  5 #include<cmath> 6  7 #include<cstring> 8  9 #include<algorithm>10 11 #include<iostream>12 13 #include<vector>14 15 #include<map>16 17 #include<set>18 19 #include<queue>20 21 #include<string>22 23 #define inf 100000000024 25 #define maxn 105026 27 #define maxm 500+10028 29 #define eps 1e-1030 31 #define ll long long32 33 #define pa pair<int,int>34 35 #define for0(i,n) for(int i=0;i<=(n);i++)36 37 #define for1(i,n) for(int i=1;i<=(n);i++)38 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)40 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)42 43 #define mod 100000000744 45 using namespace std;46 47 inline int read()48 49 {50 51     int x=0,f=1;char ch=getchar();52 53     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}54 55     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();}56 57     return x*f;58 59 }60 int l,r,n,ans,f[maxn][55][55],a[maxn];61 62 int main()63 64 {65 66     freopen("input.txt","r",stdin);67 68     freopen("output.txt","w",stdout);69 70     l=read();r=read();n=read();71     for1(i,n)a[i]=read();72     memset(f,60,sizeof(f));73     f[0][l][r]=0;74     for0(i,n-1)75      for2(j,4,51)76       for0(k,47)77        if(f[i][j][k]<inf)78        {79            for2(l,a[i+1],a[i+1]+8)80             {81                 if(l>51)break;82                 f[i+1][l][k]=min(f[i+1][l][k],f[i][j][k]+(int)sqrt(abs(l-j)));83             }84            for3(l,a[i+1],a[i+1]-8)85             {        86                 if(l<0)break;87                 f[i+1][j][l]=min(f[i+1][j][l],f[i][j][k]+(int)sqrt(abs(k-l)));88             }89        }90      ans=inf;91      for2(i,4,51)92       for0(j,47)93        ans=min(ans,f[n][i][j]);94      printf("%d\n",ans);95 96     return 0;97 98 }
View Code

 

「Poetize5」GF弹钢琴