题目大意:
第一行一个n,表示共n个月份,然后第二行分别表示一个工人的聘请工资,月薪水,解雇工资。第三行是n个月每个月需要的工人的最少数目。然后求最少花费
题解:
dp[i][j] 表示第i个月聘请j个人需要的最少花费。
状态是怎么转移的呢?
当第i-1个月聘请k个人时。
如果k<j。需要聘请新人 dp[i][j]=dp[i-1][k]+hire*(j-k)+salary*j;
否则 。。需要解雇人员 dp[i][j]=dp[i-1][k]+fire*(k-j)+salart*j;
注意:最后一个月聘请的人不需要解雇。。。。。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N=1E3+7; const ll INF=1e18+7; ll dp[N][N]; ll arr[N]; int main(){ ll n; while(cin>>n,n){ ll hire,salary,fire; cin>>hire>>salary>>fire; ll maxx=0; for(ll i=1;i<=n;i++){ cin>>arr[i]; maxx=max(arr[i],maxx); } for(ll i=0;i<=n;i++) for(ll j=0;j<=maxx;j++) dp[i][j]=INF; for(ll i=arr[1];i<=maxx;i++) dp[1][i]=hire*i+salary*i; for(ll i=2;i<=n;i++){ for(ll j=arr[i];j<=maxx;j++){ for(ll k=arr[i-1];k<=maxx;k++){ if(j>k) dp[i][j]=min(dp[i][j],dp[i-1][k]+hire*(j-k)+salary*j); else dp[i][j]=min(dp[i][j],dp[i-1][k]+fire*(k-j)+salary*j); } } } ll ans=INF; for(ll i=arr[n];i<=maxx;i++) ans=min(ans,dp[n][i]); cout<<ans<<endl; } return 0; }