又是一个典型的背包.注意贪心思路:如果你要做这辆车,你就坐满他.
(i,j)分别存坐上去的人总人数和现在的时间(,dp[i][j]) 统计来到这个状态的最小钱数
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1e2+5;
int n,k,d,s;
int dp[MAXN<<1][MAXN],ans = 1e9;
inline void update(int a, int b){
for (int i=n;i>=0;i--){//倒序背包
for (int j=b;j>=0;j--){//时间也倒序
dp[i+a][b] = min(dp[i+a][b],dp[i][j]+d+(n-i)*(b-j));
}
}
}
inline void find_ans(){
for (int i=2*n-1;i>=n;i--){
for (int j=s;j>=0;j--){
ans = min(ans,dp[i][j]);
}
}//找最小满足所有人到达的时间
if (ans==1e9) cout << "impossible";
else cout << ans;
}
int main(){
cin >> n >> k >> d >> s;
memset(dp,0x3f3f,sizeof(dp));
dp[0][0] = 0;
for (int i=0;i<k;i++){
int a,b; cin >> a >> b;
update(b,a);
}
find_ans();
}
为啥要开2*n?因为有时候搭车人数会超过n.我们可以严格限制在n里但是我懒,于是就开大一点保证无错