威威猫系列故事——拼车记
题目链接:Click Here~
题目分析:
题目要求很简单,要你求出在满足题目条件下的最小花费。应该可以看出来是动态规划,但是要做出来就要另一个境界了。本人也是属于没做出来的一种。想了好久也没想出来状态转移方程式,最后还是看了别人的博客才知道的。直接分析题目。因为题目给出的量有N个人,K辆车,和时间Ti(其实S是没有价值的)。如何把这三个变量联系到DP进去呢?我想了好久还是没想到。别人是这样解释状态转移方程式的:
i 表示第i辆车,j 表示已经走的人数,p表示当前第i辆车走了p个人
dp[i][j] = min(dp[i][j],dp[i-1][j-p]+t[i]*p+price);(j>=p)
别的细节就自己看下面的代码吧。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100 + 5;
const int INF = 1e6;
int t[N],z[N],dp[N][N];
void Init()
{
for(int i = 0;i < N;++i)
for(int j = 0;j < N;++j)
dp[i][j] = INF;
dp[0][0] = 0;
}
int main()
{
int T,n,K,D,S;
scanf("%d",&T);
while(T--)
{
Init();
scanf("%d%d%d%d",&n,&K,&D,&S);
for(int i = 1;i <= K;++i){
scanf("%d%d",&t[i],&z[i]);
dp[i][0] = 0;
}
for(int i = 1;i <= K;++i) //前k辆车
for(int j = 1;j <= n;++j) //前j个人
for(int p = 0;p <= z[i];++p){ //第i辆车走p个人
if(j < p)break;
int price = (p?D:0);
dp[i][j] = min(dp[i][j],dp[i-1][j-p]+t[i]*p+price);
}
if(dp[K][n]==INF)
printf("impossible\n");
else
printf("%d\n",dp[K][n]);
}
return 0;
}