当前位置: 首页 > news >正文

工作安排小K

[]测试连接](https://www.acwing.com/problem/content/description/5840/)
小 K 有 N 项工作等待完成,第 i 项工作需要花 ti 单位时间,必须在 di 时刻或之前完成,报酬为 pi。

假设小 K 工作时刻从 0 开始,且同一时刻只能做一项工作、工作一旦开始则不可中断或切换至其他工作,请你帮小 K 规划一下如何选择合适的工作,使小 K 可以获得最多的报酬。

输入格式

输入第一行是一个正整数 T,表示数据的组数。

接下来有 T 组数据,每组数据第一行是一个正整数 N,表示待完成工作的数量。

接下来的 N 行,每行三个非负整数 ti,di,pi,表示第 i 项工作需要花费的时间、截止时间以及报酬。

输出格式

对于每组数据,输出小 KK 能获得最多的报酬是多少。

首先是递归版本:

按照贪心考虑的话就是先考虑最早结束的,因为结束了就没办法做了,如果按照最晚开始考虑的话,会出现,虽然工作A的"最晚开始时间"早于工作B,但A的截止时间反而晚于B,这会导致决策冲突,例如A:7 10和B:3 8如果按照最晚开始时间的话A现做,做完之后B就不可以做了,但是如果按照最早截止时间的话,B做完了A还可以做呢.所以考虑按照最早截止时间考虑,对于每件事,考虑做和不做所得到的收益:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int read()
{int f = 0, sum = 0;char ch = getchar();while (!isdigit(ch)) f |= ch == '-', ch = getchar();while (isdigit(ch)) sum = sum * 10 + (ch ^ 48), ch = getchar();return f ? -sum : sum;
}
#define Len 100003
typedef pair<int,int> PII;
struct game
{int t,d,p;
};
int ans;
int n;
bool mcmp(game&a,game&b)
{return a.d<b.d;
}
void dfs(int index,int time,int sum,game arr[])
{if(index==n){ans=max(ans,sum);return;}dfs(index+1,time,sum,arr);if(time<=arr[index].start)dfs(index+1,time+arr[index].t,sum+arr[index].p,arr);}
int main()
{int ci;cin>>ci;while(ci--){cin>>n;game arr[n+2];for(int i=0;i<n;i++){cin>>arr[i].t>>arr[i].d>>arr[i].p;}sort(arr,arr+n,mcmp);ans=0;dfs(0,0,0,arr);cout<<ans<<endl;}return 0;
}

从上面的思考你是不是想到了01背包对于每件物品考虑要和不要所得到的收益,所以下面给出动态规划的版本:

定义dp[i][j],截止到时间为考虑前 i i i个工作截止时间为j的时候所能得到最大的时间状态转移方程如下:
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − c o s t [ i ] ] + v a l [ i ] ) dp[i][j]=max(dp[i-1][j],dp[i][j-cost[i]]+val[i]) dp[i][j]=max(dp[i1][j],dp[i][jcost[i]]+val[i])
可以看出当前状态只是依赖于以前的转态,所以可以使用一个一维数组来更新下一个的数组;
转态转移方程可以转化为:
d p [ j ] = m a x ( d p [ j ] , d p [ j − c o s t [ i ] . t ] + v a l [ i ] . p ) ; dp[j] = max(dp[j], dp[j - cost[i].t] + val[i].p); dp[j]=max(dp[j],dp[jcost[i].t]+val[i].p);
也可以进行空间压缩.这里使用倒序遍历来避免同一个状态被多次使用(一个工作只能做一次)

代码如下:

#pragma GCC optimize(2)
#include <bits/stdc++.h>using namespace std;const int N = 5010;struct Node
{int t, d, p; // 消耗时间, 必须在d时刻完成,报酬bool operator<(const Node &a) const{if (a.d != d)return d < a.d;else if (a.t != t)return t < a.t;}
} a[N];int n, m;
int f[N];void solve()
{memset(f, 0, sizeof(f));cin >> n;for (int i = 1; i <= n; i++){int t, d, p;cin >> t >> d >> p;a[i].t = t;a[i].d = d;a[i].p = p;}sort(a + 1, a + n + 1);for (int i = 1; i <= n; i++){for (int j = a[i].d; j >= a[i].t; j--){f[j] = max(f[j], f[j - a[i].t] + a[i].p);}}int ans = 0;for (int i = 0; i < N; i++){ans = max(ans, f[i]);}cout << ans << '\n';
}int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin >> T;while (T-- > 0){solve();}return 0;
}

对了如果你的算法已经可以比较满足题目的要求了,但是还是超时,可以试一试加上#pragma optimize(2)来碰一碰运气,说不定就过了.

相关文章:

  • Elasticsearch生产环境性能调优指南
  • Unity中GPU Instancing使用整理
  • 全方位详解微服务架构中的Service Mesh(服务网格)
  • 互联网大厂Java求职面试:Spring Cloud微服务架构与AI集成挑战
  • 如何在 Android 手机和平板电脑上下载应用程序
  • ATT Global赞助非小号全球行,引领RWA创新浪潮
  • springboot 1.x2.x依赖spring版本
  • MySQL 5.7 实战:JSON 字段提取、Base64 解码与引号问题全解析
  • 无人机电子防抖技术要点概述!
  • 20个关于Java编程语言的常见问题
  • Redis SETNX:分布式锁与原子性操作的核心
  • SPL做量化---PSY(心理线)
  • 【人工智能基础知识】
  • Mysql索引实战1
  • 2025年二级等保实施全攻略:传统架构与云等保方案深度解析
  • 系统设计应优先考虑数据流还是控制流?为什么优先考虑数据流?数据流为主、控制流为辅的架构原则是什么?控制流优先会导致哪些问题?
  • C++ 11(1):
  • spring的注入方式都有什么区别
  • 2024CCPC辽宁省赛 个人补题 ABCEGJL
  • 分类预测 | Matlab实现PNN概率神经网络多特征分类预测
  • 电子网站建设ppt模板/赛雷猴是什么意思
  • 建网站视频教程/开发外包网站
  • 如何查看网站的点击量/网店运营培训
  • 政府网站信息化建设调查表/潍坊关键词优化排名
  • 丹灶做网站/seopc流量排名官网