#include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <map> #include <set> using namespace std ; #define N 100010 #define int long long int n , m ; struct node { int d,p ; bool operator < ( const node &x ) const { return p>x.p; } } a[ N ] ; bool cmp( node a , node b ) { return a.d==b.d?a.p>b.p:a.d<b.d; } priority_queue< node > q ; signed main() { scanf( "%lld" , &n ) ; for( int i = 1 ; i <= n ; i ++ ) { scanf( "%lld%lld" , &a[i].d , &a[i].p ) ; } sort(a+1,a+n+1,cmp); int ans = 0 ; for( int i = 1 ; i <= n ; i ++ ) { if( a[i].d<=(int)q.size() ) { if( q.top().p<a[i].p ) { ans += a[i].p-q.top().p ; q.pop() ; q.push(a[i]) ; } } else q.push(a[i]) , ans += a[ i ].p ; } printf( "%lld\n" , ans ) ; }
时间: 2024-04-28 12:22:23 浏览: 231
这是一段 C++ 代码,实现了一道贪心算法的题目。代码的作用是求解一道题目。在这道题目中,有 $n$ 个任务,每个任务有一个截止时间 $d_i$ 和一个收益 $p_i$。假设你只有一个机器可以执行这些任务。每个任务不能被中断,只能在截止时间前被执行完,执行完一个任务可以获得相应的收益。任务可以以任意顺序执行,但是每个任务都必须在截止时间之前执行完。问你最多可以获得多少收益。
具体而言,这段代码首先读入任务的数量 $n$ 和每个任务的截止时间 $d_i$ 和收益 $p_i$,然后按照截止时间和收益排序。接着,用一个优先队列 $q$ 存储当前可以执行的任务,每次选择一个还未执行的任务,如果当前时间小于等于队列的大小,说明当前任务可以被执行,如果队列里面已经有任务在执行,就比较当前任务的收益和队列里面的任务收益,如果当前任务的收益比队列里面的任务收益高,就替换掉队列里面的任务,并把收益差加到答案里。如果当前时间大于队列的大小,说明当前任务无法被执行,直接放到队列里面。最后输出答案。
这段代码的时间复杂度为 $O(n \log n)$,其中最耗时的是排序操作。
相关问题
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<iostream> #include<algorithm> #include<map> #include<stack> #include<queue> #include<vector> #include<set> #include<string> #define dd double #define ll long long dd PI = acos(-1); using namespace std; const ll MAXN = 1e5 + 5; const ll INF = 1e9 + 5; ll n; struct node { ll x, y; }s[5000]; ll dp[MAXN] = { 0 }; int main() { //ios::sync_with_stdio(false); ll n, m; cin >> n >> m; for (ll i = 1; i <= n; i++) { cin >> s[i].x >> s[i].y; } for (ll i = 1; i <= n; i++) { for (ll j = m; j >= s[i].x; j--) { dp[j] = max(dp[j], dp[j - s[i].x] + s[i].y); } } cout << dp[m] << endl; }
这是一段动态规划求解背包问题的代码,用来求解一个容量为m的背包能够装下的最大价值。具体实现过程为:
1. 定义一个结构体node,用来存储物品的重量和价值。
2. 读入物品数量n和背包容量m,然后读入每个物品的重量和价值。
3. 使用二重循环,遍历每一个物品,然后从大到小枚举背包容量j,更新dp[j]的值,表示容量为j的背包能够装下的最大价值。
4. 最后输出dp[m]的值,即容量为m的背包能够装下的最大价值。
值得注意的是,这段代码中还定义了一些常量和宏定义,如MAXN、INF等,以及一些头文件和命名空间的使用。
将下列c++代码转为Java#include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> using namespace std; typedef long long LL; const int N=3000009; int a[8];void move(int x,int y,int t) { while(a[x]) { if(a[t]==0) { a[t]++;a[y]++; printf("%c%c+\n",t+'A',y+'A'); } a[t]--; a[x]--; printf("%c%c-\n",t+'A',x+'A'); } } int main() { int i,j,n; for(i=0;i<8;i++) scanf("%d",&a[i]); int s1=a[0]+a[2]+a[5]+a[7],s2=a[1]+a[3]+a[4]+a[6]; if(s1!=s2) { printf("IMPOSSIBLE\n"); return 0; }move(2,0,1); move(5,0,4); move(7,0,4); move(6,4,5); move(1,4,0); move(3,4,0); while(a[0]--) printf("AE-\n"); return 0; }
在Java中,需要去掉头文件,并使用Java中的数据结构代替C++中的数据结构。同时,Java中需要使用System.out.print代替printf。
以下是转换后的Java代码:
import java.util.*;
public class Main {
static long N = 3000009;
static int[] a = new int[8];
static void move(int x, int y, int t) {
while (a[x] != 0) {
if (a[t] == 0) {
a[t]++;
a[y]++;
System.out.println((char)(t+'A') + "" + (char)(y+'A') + "+");
}
a[t]--;
a[x]--;
System.out.println((char)(t+'A') + "" + (char)(x+'A') + "-");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 8; i++) {
a[i] = sc.nextInt();
}
int s1 = a[0] + a[2] + a[5] + a[7];
int s2 = a[1] + a[3] + a[4] + a[6];
if (s1 != s2) {
System.out.println("IMPOSSIBLE");
return;
}
move(2, 0, 1);
move(5, 0, 4);
move(7, 0, 4);
move(6, 4, 5);
move(1, 4, 0);
move(3, 4, 0);
while (a[0] != 0) {
System.out.println("AE-");
a[0]--;
}
}
}
阅读全文