• PAT顶级 1002 Business (35分)(0/1背包)


    思路:

    1.每份工作只有做和不做,问最大利润,自然就能想到0/1背包问题;
    2.设dp[i][j]dp[i][j]表示用jj天的时间,在前ii个工程中所能获得的最大利润,设wk[i]wk[i]为第ii个工作,wk[i].prowk[i].prowk[i].costwk[i].costwk[i].ddlwk[i].ddl分别代表利润、花费的时间和截止日期,则我们有
    dp[i][j]={dp[i1][j]j<wk[i].costmax(dp[i1][j],dp[i1][jwk[i].cost]+wk[i].pro)wk[i].costjwk[i].ddlmax(dp[i1][j],dp[i][j1])j>wk[i].ddldp[i][j]= egin{cases} dp[i-1][j]&j<wk[i].cost\ max(dp[i-1][j],dp[i-1][j-wk[i].cost]+wk[i].pro)& wk[i].cost leq j leq wk[i].ddl\ max(dp[i-1][j],dp[i][j-1])& j>wk[i].ddl end{cases}
    和普通背包不同的就是在日期超过ddlddl时我们无法通过完成第ii份工作来达到第jj天,因此有第三行的递推式;
    3.相同的几个工作,我们肯定需要先完成截止日期近的工作,因此需要对数组内容按截止日期进行排序;

    代码:

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=52;
    int n,lmt=0;
    vector<int> dp[maxn];
    struct work{int pro,cost,ddl;}wk[maxn];
    void solve(){
    	for(int i=0;i<=n;i++) dp[i].resize(lmt+1);
    	sort(wk+1,wk+n+1,[](const work& w1,const work& w2){return w1.ddl<w2.ddl;});
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=lmt;j++){
    			if(j>=wk[i].cost&&j<=wk[i].ddl)
    				dp[i][j]=max(dp[i-1][j],dp[i-1][j-wk[i].cost]+wk[i].pro);
    			else if(j<wk[i].cost) dp[i][j]=dp[i-1][j];
    			else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    		}
    	}
    	cout<<dp[n][lmt];
    }
    int main(){
    //	freopen("Sakura.txt","r",stdin);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>wk[i].pro>>wk[i].cost>>wk[i].ddl;
    		lmt=max(lmt,wk[i].ddl);
    	}
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    常见逻辑谬误
    4 WPF依赖属性
    11 WPF样式和行为
    17 WPF控件模板
    3 WPF布局
    4.6.3 The LRParsing Algorithm
    4.6 Introduction to LR Parsing: Simple LR
    19 WPF 数据绑定
    分布式系统部署、监控与进程管理的几重境界
    运维知识体系
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308741.html
Copyright © 2020-2023  润新知