1070-诡异的电梯【Ⅰ】
内存限制:64MB 时间限制:1000ms Special Judge: No
题目描述:
新的宿舍楼有 N(1≤N≤100000) 层 and M(1≤M≤100000)个学生. 在新的宿舍楼里, 为了节约学生的时间也为了鼓励学生锻炼身体, 所以规定该宿舍楼里的电梯在相邻的两层之间是不会连续停下(即,如果在第2层停下就不能在第3层停下。).所以,如果有学生在相邻的两层之间要停下, 则其中的一部分学生必须选择走楼梯来代替。规定:一个人走下一层楼梯的花费为A,走上一层楼梯的花费为B。(1≤A,B≤100)现在请你设计一个算法来计算出所有学生走楼梯花费的最小费用总和。 所有的学生一开始都在第一层,电梯不能往下走,在第二层的时候电梯可以停止。
输入描述:
输入有几组数据T。T(1≤T≤10) 每组数据有N (1≤N≤100000),M(1≤M≤100000),A,B(1≤A,B≤100)。 接下来有M个数字表示每个学生想要停的楼层。
输出描述:
输出看样例。
样例输入:
复制
1 3 2 1 1 2 3
样例输出:
Case 1: 1
题解:dp[i]表示到达i层的最小花费。到达i层有两种情况。
第一种:电梯停在i-1层,所以i层的人要么从i-1上一层,或者从i+1层下一层。得出dp[i-1]+num[i]*min(a,b)
第二种:电梯停在i层,因此i-1层的人,要么从第i层下一层,要么从第i-2层上一层。得出dp[i-2]+num[i-1]*min(a,b)
dp[i]=min(dp[i-1]+num[i]*min(a,b),dp[i-2]+num[i-1]*min(a,b));
顺便吐槽一句,这题的数据可能不是那么严谨。
#include <iostream>
using namespace std;
const int inf= 0x3f3f3f3f;
int dp[100001],num[100001];
int main ()
{
int T,t,n,m,a,b,tmp;
cin>>T;
for (int t=1;t<=T;t++)
{
cin>>n>>m>>a>>b;
fill(dp,dp+n+1,inf);
fill(num,num+n+1,0);
for (int i=0;i<m;i++)
{
cin>>tmp;
num[tmp]++;//统计要到每层的人数
}
dp[1]=dp[2]=0;
for (int i=3;i<=n;i++)
dp[i]=min(dp[i-1]+num[i]*min(a,b),dp[i-2]+num[i-1]*min(a,b));
cout<<"Case "<<t<<": "<<dp[n]<<endl;
}
return 0;
}