题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4526
方法:设F[x,m]为在m分钟,已经累积走了x人所花了多少钱最少为多少,设在第i分钟可以累计走的最大人数是c(i),出租车在第i分钟每人需要的额外等待价格p(i),有剩余作为数量a(i),出租车基础价格p,学生总数totalStdCount,总时间为M,状态转移方程是:
F[x,m] = Min{ F[i,m-1] + (x-i)*p(m)+p | 0<=i<=c(m-1) and i<=x<=Min(c(m-1)+a(m) , totalStdCount) and x-i <=a(m)} ;
最后F(totalStdCount,M)为最优解。
感想:思路要清楚。
代码:

#include<iostream> #include<algorithm> using namespace std; int const MAX =0x3f3f3f3f; int MyAdd(int x,int y) { if(x==MAX||y==MAX) return MAX; return x+y; } int multp(int x,int y,int z) { if(z==0 || y ==0) return 0; return x+y*z; } int main() { int tc=0,t; cin>>t; int stdCount,carCount,initPrice,totalTime; int carsTime[101]; int carsSets[101]; int records[101][101]; while(tc<t) { scanf("%d %d %d %d",&stdCount,&carCount,&initPrice,&totalTime); memset(carsSets,0,sizeof(carsSets)); for(int x=0;x<=100;x++) { for(int y=0;y<=100;y++) { if(x!=0) records[x][y]=MAX; else records[x][y] = 0; } } int i = 1; int a,b,ss=0; while(i<=carCount) { scanf("%d %d",&a,&b); carsTime[i] = a; carsSets[i] = b; i++; } int sumSetsCount = carsSets[1]; for( i=0;i<=stdCount;i++) { if(i<=sumSetsCount) { records[i][1] = multp(initPrice,carsTime[1],i); } } for(int m=2;m<=totalTime;m++) { sumSetsCount+=carsSets[m]; int t_re; for(int i=0;i<=sumSetsCount && i<=stdCount;i++) { for(int j=0;j<=i;j++) { if(i-j<=carsSets[m]) { t_re = MyAdd(records[j][m-1] , multp(initPrice,carsTime[m],i-j)); if(t_re < records[i][m]) records[i][m] = t_re; } } } } if(records[stdCount][totalTime]==MAX) cout<<"impossible"<<endl; else cout<<records[stdCount][totalTime]<<endl; tc++; } return 0; }