链接:https://ac.nowcoder.com/acm/contest/15397/B
来源:牛客网
小Z为训练营同学预订了n(1≤n≤500)个回程航班,每个航班的同学数依次为a1,a2,…,an(1≤ai≤106)。现在只有一个司机,司机需要严格按照航班顺序依次将第1到第n个航班的同学送往机场。该司机可从租车公司租到任意载客量的车,但是最多只能租g次(1<=g<=n),并且每次只能租1辆。假设司机用载客量为m的车送ai个同学到机场(当然要求不超载),那么就造成了m-ai的载量浪费。请问该司机送完所有批次同学到机场后,最低的载量浪费是多少?
将数组分成g+1份,求怎么分可以使(maxi*leni) - sumi之和最小。
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn = 510; const ll mod = 100000007; const int INF = 1e9; int n,m; int a[maxn]; int sum[maxn],Max[maxn][maxn]; int dp[maxn][maxn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; /* 求区间最大值 */ for(int i=1;i<=n;i++) { Max[i][i]=a[i]; for(int j=i+1;j<=n;j++) Max[i][j]=max(Max[i][j-1],a[j]); } //初始化数组 for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) dp[i][j]=INF; dp[0][0]=0; for(int i=1;i<=n;i++) { for(int k=0;k<i;k++) { for(int j=0;j<m;j++) dp[i][j+1]=min(dp[i][j+1],dp[k][j]+ Max[k+1][i]*(i-k) - (sum[i]-sum[k]) ); } } int ans=INF; for(int j=0;j<=m;j++) ans=min(ans,dp[n][j]); printf("%d",ans); return 0; }