标签:
新的宿舍楼有 N(1≤N≤100000) 层 and M(1≤M≤100000)个学生. 在新的宿舍楼里, 为了节约学生的时间也为了鼓励学生锻炼身体, 所以规定该宿舍楼里的电梯在相邻的两层之间是不会连续停下(即,如果在第2层停下就不能在第3层停下。).所以,如果有学生在相邻的两层之间要停下, 则其中的一部分学生必须选择走楼梯来代替。规定:一个人走下一层楼梯的花费为A,走上一层楼梯的花费为B。(1≤A,B≤100)现在请你设计一个算法来计算出所有学生走楼梯花费的最小费用总和。 所有的学生一开始都在第一层,电梯不能往下走,在第二层的时候电梯可以停止。
1 3 2 1 1 2 3
Case 1: 1
题目讲解:题目的状态转移方程是比较难想,但是画一下图就能发现转移方程;
下面图解now代表当前的楼层:到达每一个楼层,共有下面四种情况;
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<string> 7 #include<cmath> 8 using namespace std; 9 const int N = 1e5+10; 10 const int MAX=0x3fffffff; 11 int dp[N],ma[N]; 12 int main() 13 { 14 int T,m,n,down,up,cout=1; 15 scanf("%d",&T); 16 while(T--) 17 { 18 int x; 19 memset(ma,0,sizeof(ma)); 20 fill(dp,dp+N,MAX); 21 dp[0]=dp[1]=dp[2] = 0; 22 scanf("%d %d %d %d",&n,&m,&down,&up); 23 int ab = min(down,up); 24 for(int i = 1;i<=m; i++) 25 { 26 scanf("%d",&x); 27 ma[x]++; 28 } 29 for(int i = 3; i<=n; i++) 30 { 31 dp[i] =min( dp[i],dp[i-2]+ma[i-1]*ab); 32 if(i>=4) 33 { 34 int temp = MAX; 35 temp = min(ma[i-2]*up*2+ma[i-1]*up,ma[i-2]*down+ma[i-1]*down*2);//同上同下 36 temp = min(temp,ma[i-2]*down+ma[i-1]*up);//一下一上 37 temp = min(temp,ma[i-2]*2*up+ma[i-1]*down*2);//一上一下 38 dp[i]=min(dp[i],temp+dp[i-3]); 39 } 40 } 41 printf("Case %d: %d\n",cout++,dp[n]); 42 } 43 return 0; 44 }
标签:
原文地址:http://www.cnblogs.com/lovychen/p/4423276.html