Installing Apps Gym - 101623I(背包+贪心)

2024-04-15 23:48

本文主要是介绍Installing Apps Gym - 101623I(背包+贪心),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:
下载app,每个app有下载容量和安装容量。内存必须满足下载容量才能下载,最后所占空间为安装容量。
求c的内存最多可以安装多少个app。

思路:
比赛的时候wzf猜了个结论,就是按照 d-s排序从大到小遍历,然后按照普通背包跑然后过了。

事后想想的话,其实可以从背包转移方程看出来:
d p [ j − n u m + a [ i ] . s ] = m a x ( d p [ j − n u m + a [ i ] . s ] , d p [ j − n u m ] + 1 ) , n u m = m a x ( a [ i ] . s , a [ i ] . d ) , n u m ≤ j ≤ c dp[j - num + a[i].s] =max(dp[j-num+a[i].s],dp[j - num] + 1),num=max(a[i].s,a[i].d),num≤j≤c dp[jnum+a[i].s]=max(dp[jnum+a[i].s],dp[jnum]+1)num=max(a[i].s,a[i].d)numjc
可以看出来, d − s d-s ds越大,就会有越多的状态更新不到,就像是减少了c的大小。将 d − s d-s ds大的放前面可以使得这些不能更新到的状态值尽可能小,“损失”也就尽可能小。
所以 d − s d-s ds大的放在前面可以尽可能的使得预留的空间大,使得能尽量装下这些物品。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;const int INF = 0x3f3f3f3f;
const int maxn = 10005;int dp[maxn],pre[505][maxn];struct Node {int d,s;int id;
}a[maxn];int cmp(Node a,Node b) {return a.d - a.s > b.d - b.s;
}int main() {int n,c;scanf("%d%d",&n,&c);for(int i = 1;i <= n;i++) {scanf("%d%d",&a[i].d,&a[i].s);a[i].id = i;}sort(a + 1,a + 1 + n,cmp);for(int i = 1;i <= n;i++) {int num = max(a[i].d,a[i].s);for(int j = 0;j <= c;j++) pre[i][j] = j;for(int j = c;j >= num;j--) {if(dp[j - num + a[i].s] < dp[j - num] + 1) {pre[i][j - num + a[i].s] = j - num;dp[j - num + a[i].s] = dp[j - num] + 1;}}}int mx = 0,pos = 0;for(int i = 1;i <= c;i++) {if(dp[i] > mx) {mx = dp[i];pos = i;}}vector<int>ans;for(int i = n;i >= 1;i--) {if(pre[i][pos] != pos) {ans.push_back(a[i].id);pos = pre[i][pos];}}printf("%d\n",ans.size());reverse(ans.begin(), ans.end());for(int i = 0;i < ans.size();i++) {printf("%d ",ans[i]);}return 0;
}

这篇关于Installing Apps Gym - 101623I(背包+贪心)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907261

相关文章

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

usaco 1.3 Barn Repair(贪心)

思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。 做法: 1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~ 2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 an

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl