还是看了别人的思路才做出来..
http://blog.csdn.net/ice_crazy/article/details/7575703
分析:
i为月数,l为人数,num[i]为第i月需要多少人,total是最多要多少人。
dp[i][l]=min(dp[i-1][k]+l*s+k>l?(k-l)*f:(l-k)*h) num[i-1]<=k<=total
ans=min(dp[最后一月][k]) num[最后一月]<=k<=total
2012-05-17
*/
//递推方程 dp[i][l] = minn(dp[i][l],dp[i-1][k]+l*s+(k>l?(k-l)*f:(l-k)*h))
// k>=num[i-1]&&k<=total;
#include<stdio.h>
int dp[13][1001];
int num[13];
int minn(int a,int b)
{
return a>b?b:a;
}
int main()
{
int ans,total;
int s,f,h;
int i,m,k,n,j,l;
while(1)
{
scanf("%d",&m);
if(m==0)break;
total = -1;
scanf("%d%d%d",&h,&s,&f);
//找出最大人数
for(i=0;i<m;i++)
{
scanf("%d",&num[i]);
if(total < num[i])total=num[i];
}
if(total==0)
{
printf("0\n");
return 0;
}
//第一个月初始化
for(k=num[0];k<=total;k++)
dp[0][k] = k*(h+s);
for(l=1;l<m;l++)
{
for(n=num[l];n<=total;n++)
{
if(n > num[l-1])
dp[l][n]=(n-num[l-1])*h+dp[l-1][num[l-1]]+n*s;
else
dp[l][n]=(num[l-1]-n)*f+dp[l-1][num[l-1]]+n*s;
for(j=num[l-1]+1;j<=total;j++)
{
if(j>n)
dp[l][n]=minn(dp[l][n],dp[l-1][j]+n*s+(j-n)*f);
else
dp[l][n]=minn(dp[l][n],dp[l-1][j]+n*s+(n-j)*h);
}
}
}
ans = 0x7fffffff;
for(j=num[m-1];j<=total;j++)
ans = minn(ans,dp[m-1][j]);
printf("%d\n",ans);
}
return 0;
}