dp[i][j]表示前i辆车送走j个acmer的最小花费,然后就有dp[i][j]=dp[i-1][j-k]+k*t+d;(t为车辆到达的时间,d为花费),
AC代码:
//dp[i][j]表示前i辆车载j个人花费的钱
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 0xfffffff
using namespace std;
int main()
{
int t;
cin>>t;
int dp[105][105],a[105],p[105];
while(t--)
{
int n,k,d,s,i,j;
int sum=0;
cin>>n>>k>>d>>s;
for(i=1;i<=k;i++)
{
cin>>a[i]>>p[i];
sum+=p[i];
}
if(sum<n) { //如果总的空座小于人数,就是不可能的
cout<<"impossible"<<endl;
continue;
}
for(i=0;i<=k;i++)
for(j=0;j<=n;j++)
dp[i][j]=inf; //因为要求最小的,所以dp要初始化成尽量大的值
dp[0][0]=0;
for(i=1;i<=k;i++)
{
for(j=0;j<=n;j++)
dp[i][j]=dp[i-1][j]; //就算第i辆车不载人也要花前i-1辆的钱
for(j=0;j<=n;j++)
{
if(j>4*i) break; //每辆车最多坐四个人,所以已经载走的人数不可能大于4*i
for(int u=0;u<=p[i];u++)
{
if(j>=u)
dp[i][j]=min(dp[i][j],dp[i-1][j-u]+u*a[i]+d);
}
}
}
cout<<dp[k][n]<<endl;
}
return 0;
}