• O


    题目大意:

    第一行一个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;
    }
  • 相关阅读:
    增量学习中的自我训练
    半监督学习和直推学习的区别
    LeetCode: Word Break
    LeetCode: Linked List Cycle
    LeetCode: Reorder List
    LeetCode: Binary Tree Traversal
    LeetCode: LRU Cache
    LeetCode: Insertion Sort List
    LeetCode: Sort List
    LeetCode: Max Points on a Line
  • 原文地址:https://www.cnblogs.com/Accepting/p/12463535.html
Copyright © 2020-2023  润新知