102
其实跟背包问题是一样的,对一份工作,就是要不要的问题。所以一开始为了好处理,先排序一下。
m在这边其实相当于限制条件,跟费用没什么关系,所以就是一维的动态类背包问题,dp[n]表示前n份工作所能获得的最大值;
dp[n]=max(dp[n-1], Max+s[n].money);
解释一下这个方程:
(1)第n件工作不选时,这时dp[n]=dp[n-1];
(2)第n件工作选时,此时先往前排除起冲突的一些工作,然后在剩余的选最大的dp值,记为Max, 然后加上本身的s[n].money,即dp[n]=Max+s[n].money;
AC代码:
# include <stdio.h> # include <algorithm> using namespace std; struct node{ int begin; int end; int money; }; struct node s[1010]; int compare(struct node a, struct node b){//排序函数 if(a.end!=b.end); return a.end<b.end; return a.begin<b.begin; } int dp[1010];//dp[n]表示前n件工作所能获得的最大值 int main(){ int t, i, j, k, n, m, cnt, l; int num1, num2, num3; scanf("%d", &t); for(i=1; i<=t; i++){ scanf("%d%d", &m, &n); cnt=1; for(j=1; j<=n; j++){ scanf("%d%d%d", &num1, &num2, &num3); if(m>=num2){//根据条件剔除掉不可能的一些数据 s[cnt].begin=num1; s[cnt].end=num2; s[cnt].money=num3; cnt++; } } sort(s+1, s+cnt, compare);//进行排序 dp[0]=0; for(j=1; j<=cnt-1; j++){ dp[j]=dp[j-1];//假如第n个不选 k=j-1; while(k>=1&&s[k].end>=s[j].begin){//往前排除与第n个起冲突的 k--; } int Max=-1; for(l=k; l>=0; l--){//往前选剩余的最大值 if(dp[l]>Max){ Max=dp[l]; } } dp[j]=max(Max+s[j].money, dp[j]);//更新dp[n]; } printf("%d\n", dp[cnt-1]); } return 0; }