题意:一个电梯只能上升而且不能在连续的2层停止,每个人上和下一层,分别花费体力值为a,b,问满足所需人的需求花费的最小体力值是多少?
思路:dp,电梯肯定是停的越多越好,dpi表示的是在第i层停止后使所有顾客都满足的最小花费,那么上一次停止的位置只可能是i-2或者是i-3,然后使得这中间的楼层的人都满足,讨论2*2就ok了!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf=0x7f7f7f7f;
const int maxn=1e5+10;
int n,m,num[maxn],a,b,dp[maxn];
int main(){
int t;cin>>t;int k;int count=1;
while(t--){
memset(num,0,sizeof(num));
memset(dp,inf,sizeof(dp));
scanf("%d%d%d%d",&n,&m,&a,&b);
for(int i=1;i<=m;i++){
scanf("%d",&k);num[k]++;
}
dp[1]=dp[2]=0;
for(int i=3;i<=n;i++){
dp[i]=min(dp[i],dp[i-2]+min(num[i-1]*a,num[i-1]*b));
if(i>3){
dp[i]=min(dp[i],dp[i-3]+num[i-2]*b+num[i-1]*2*b);
dp[i]=min(dp[i],dp[i-3]+num[i-2]*b+num[i-1]*a);
dp[i]=min(dp[i],dp[i-3]+num[i-2]*2*a+num[i-1]*2*b);
dp[i]=min(dp[i],dp[i-3]+num[i-2]*2*a+num[i-1]*a);
}
}
printf("Case %d: ",count++);
printf("%d\n",dp[n]);
}
}