DP.
设状态dp[i][j]表示j辆车后还剩余i个人的花费,枚举一个车的座位k,加上剩下人数i,注意i+k不能超过n,就很容易dp了。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int inf=(1<<25); int dp[105][105]; struct Car{ int ti,zi; }cars[110]; int main(){ int T,n,k,d,s,cnt,t,z; scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&n,&k,&d,&s); cnt=0; for(int i=1;i<=k;i++){ scanf("%d%d",&t,&z); if(t<=s){ cnt++; cars[cnt].ti=t; cars[cnt].zi=z; } } for(int i=0;i<=n;i++) for(int j=0;j<=cnt;j++) dp[i][j]=inf; dp[n][0]=0; for(int j=1;j<=cnt;j++){ for(int i=0;i<=n;i++){ if(i==0){ dp[i][j]=dp[i][j-1]; for(k=1;k<=cars[j].zi;k++){ if(i+k>n) break; dp[i][j]=min(dp[i][j],dp[i+k][j-1]+k*(cars[j].ti-cars[j-1].ti)+d); } } else{ dp[i][j]=dp[i][j-1]+i*(cars[j].ti-cars[j-1].ti); for(k=1;k<=cars[j].zi;k++){ if(k+i>n) break; dp[i][j]=min(dp[i][j],dp[i+k][j-1]+(i+k)*(cars[j].ti-cars[j-1].ti)+d); } } } } int ans=inf; for(int i=0;i<=cnt;i++){ ans=min(ans,dp[0][i]); } if(ans!=inf) printf("%d ",ans); else puts("impossible"); } return 0; }