http://acm.hdu.edu.cn/showproblem.php?pid=4283
三维dp
ans [ l ][ r ][ k ] 表示从 l 到 r 这一段 第一个出去的人需要 *k
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=102; const int INF=0x0fffffff; int a[N]; int ans[N][N][N]; int dp(int l,int r,int k) { if(ans[l][r][k]!=-1) return ans[l][r][k]; if(r<l) { ans[l][r][k]=0; return ans[l][r][k]; } if(l==r) { ans[l][r][k]=a[l]*k; return ans[l][r][k]; } ans[l][r][k]=INF; for(int i=l;i<=r;++i) { ans[l][r][k]=min(ans[l][r][k],a[l]*(i-l+k)+dp(l+1,i,k)+dp(i+1,r,i-l+k+1)); } return ans[l][r][k]; } int main() { int T,n; scanf("%d",&T); for(int ca=1;ca<=T;++ca) { scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%d",&a[i]); } memset(ans,-1,sizeof(ans)); printf("Case #%d: ",ca); printf("%d\n",dp(0,n-1,0)); } return 0; }