牛客—codeforces(贪心+01背包)

题目:codeforces
来自大佬的分析:
这道题还是有点意思的,由于本题的做题选择会影响最后的得分,所以需要知道每一道题的优先级。下面我们来推导一下,如何来选择做题顺序,即每一道题的优先级。
对于两道题t1,t2来说,有两种做题顺序,如下图的C12,C21,我们定义P1为t1的每分钟减小的分数,T1为做题需要的时间
两道题的初始总分数为sum(最大分数之和)

得分C12=sum-T1P1-(T1+T2)P2;
得分C12=sum-T2
P2-(T1+T2)P1;
则 C12-C21=T2
P1-T1
P2
要判断两道题的大小,这上式同时除T1*T2的P1/T1-P2/T2 这样我们就发现了优先级函数为P/T即每分钟减小分数除需要的做题时间
排好序之后,进行01背包的dp算法。
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[52][100002],n,t,Max=-1;
typedef struct Node{
	ll v,c,w;
}Node;
Node a[52];
bool cmp(Node &A,Node &B){
	//return 1.0*A.c/A.w>1.0*B.c/B.w;
	return A.c*B.w>B.c*A.w;
}
int main(){
	
	scanf("%d %d",&n,&t);
	for(int i=0;i<n;i++) scanf("%lld",&a[i].v);
	for(int i=0;i<n;i++) scanf("%lld",&a[i].c);
	for(int i=0;i<n;i++) scanf("%lld",&a[i].w);
	
     sort(a,a+n,cmp);
     for(int i=0;i<n;i++){
     	for(int j=0;j<=t;j++){
     		if(a[i].w>j) dp[i+1][j]=dp[i][j];
     		else dp[i+1][j]=max(dp[i][j],dp[i][j-a[i].w]+a[i].v-j*a[i].c);
     		Max=max(Max,dp[i+1][j]);
		 }
	 }
	printf("%lld\n",Max);
	
	
	
	return 0;
}

### 牛客 BM4 链表反转的 C++ 实现 链表反转是一个经典的算法问题,其核心思想是从头到尾遍历原链表,在遍历时改变节点指向的方向。以下是基于牛客网 BM4 的具体实现。 #### 方法描述 通过迭代的方式完成链表反转操作。定义三个指针变量 `prev`、`curr` 和 `nextNode` 来分别表示前驱节点、当前节点以及下一个节点。初始状态下,`prev` 设为 `nullptr` 表示新链表的末尾为空;随后逐步移动这些指针并调整它们之间的连接关系直到整个链表被完全翻转[^1]。 #### 代码实现 下面提供了一个完整的C++程序来解决这个问题: ```cpp #include <iostream> using namespace std; // 定义单向链表结构体 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; ListNode* reverseList(ListNode* head) { ListNode *prev = nullptr, *curr = head; while (curr != nullptr){ ListNode* nextTemp = curr->next; // 暂存后续节点 curr->next = prev; // 反转当前节点指针方向 prev = curr; // 移动prev和curr向前推进一步 curr = nextTemp; } return prev; // 返回新的头部 } void printList(ListNode* node){ // 辅助函数用于打印链表内容 while(node!=nullptr){ cout<<node->val<<" "; node=node->next; } cout<<"\n"; } int main(){ // 创建测试用例:1 -> 2 -> 3 -> 4 -> 5 ListNode* list=new ListNode(1); list->next= new ListNode(2); list->next->next= new ListNode(3); list->next->next->next= new ListNode(4); list->next->next->next->next= new ListNode(5); cout << "Original List: "; printList(list); // 打印原始列表 ListNode* reversedHead = reverseList(list); // 调用reverseList方法得到逆序后的首地址 cout << "Reversed List: "; printList(reversedHead); // 打印逆转之后的结果 return 0; } ``` 此段代码首先构建了一个简单的单项链表实例化对象,并调用了 `reverseList()` 函数对其进行倒置处理后再输出结果验证正确性。 #### 复杂度分析 时间复杂度 O(n),其中 n 是链表长度。因为只需一次扫描即可完成全部修改工作。 空间复杂度 O(1),只使用了固定数量额外的空间存储临时变量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值