HDU1158 动态规划

来源:互联网 发布:网络舆论聚焦热点事件 编辑:程序博客网 时间:2024/06/01 10:29

还是看了别人的思路才做出来..

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;elsedp[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);elsedp[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;}