题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1158
解题报告:自我感觉这道题目的状态方程不太容易。
刚开始用一维的搞,这么也得不到正确答案,后来想有月份、人数,应该用二维的。
首先雇主要在第n月花钱最少,一定是在第n-1月花钱也是最少,一定具有最有子结构,可以想到动态规划;
如果第n个月的需要的人数比第n-1个月的多,则需要本月需要(need[n]-need[n-1])*hire+need[n]*salary的钱
如果第n个月的需要的人数比第n-1个月的少,则需要本月需要(need[n-1]-need[n])*fire+need[n]*salary的钱
假设第n-1个月雇佣k个人是最有子结构;
则状态方程:dp[i][j]=dp[i][k]+(need[n]-need[n-1])*hire+need[n]*salary
或dp[i][j]=dp[i][k]+(need[n-1]-need[n])*fire+need[n]*salary
扫描二维码关注公众号,回复:
1240593 查看本文章
code:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF = 0x7fffffff; int hire,salary,fire; int need[15],dp[15][505]; int main() { int n,mini,maxn,ans; while(scanf("%d",&n)&&n) { maxn=0; scanf("%d %d %d",&hire,&salary,&fire); for(int i=1;i<=n;i++) { scanf("%d",&need[i]); maxn=max(maxn,need[i]); } if(maxn==0) { printf("0\n"); continue; } memset(dp,0,sizeof(dp)); for(int i=need[1];i<=maxn;i++) { dp[1][i]=(hire+salary)*i; } int temp; for(int i=2;i<=n;i++) { for(int j=need[i];j<=maxn;j++) { mini=INF; for(int k=need[i-1];k<=maxn;k++) { if(j>=k) { temp=dp[i-1][k]+(j-k)*hire+j*salary; } else { temp=dp[i-1][k]+(k-j)*fire+j*salary; } mini=min(mini,temp); } dp[i][j]=mini; } } ans=INF; for(int i=need[n];i<=maxn;i++) { if(ans>dp[n][i]) ans=dp[n][i]; } printf("%d\n",ans); } return 0; }