标签:
先po原题
[HDU 2111]http://acm.hdu.edu.cn/showproblem.php?pid=2111
话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了。显然,作为多年拼搏的商人,XHD不会坐以待毙的。
一天,当他正在苦思冥想解困良策的时候,突然想到了自己的传家宝,那是公司成立的时候,父亲作为贺礼送来的一个锦囊,徐父当时交代,不到万不得已的时候,不要打开它。“现在不正是最需要的时候吗?”,一边想,XHD一边找到了这个精心保管的锦囊,打开一看,里面只有一句话“杭城北麓千人洞有宝”。
二话不说,XHD拿起一个大口袋就出发了,这个千人洞他是知道的,小的时候,爸爸曾经带他来过这个隐蔽的路口,并告诉他,这是千人洞。他现在才明白爸爸当初这句话的含义。
尽管有点印象,XHD还是花了很大的精力才找到这个异常隐蔽的洞口,走进一看,几乎惊呆了,真的是眼花缭乱!不过尽管宝贝的种类不少,但是每种宝贝的量并不多,当然,每种宝贝单位体积的价格也不一样,为了挽救HDU,现在请你帮忙尽快计算出来XHD最多能带回多少价值的宝贝?
假设宝贝可以分割,分割后的价值和对应的体积成正比)Input
输入包含多个测试实例,每个实例的第一行是两个整数v和n(v,n<100),分别表示口袋的容量和宝贝的种类,接着的n行每行包含2个整数pi和mi(0<pi,mi<10) ,分别表示某种宝贝的单价和对应的体积,v为0的时候结束输入。
Output
对于每个测试实例,请输出XHD最多能取回多少价值的宝贝,每个实例的输出占一行。Sample Input
2 2
3 1
2 3
0
Sample Output
5
直接敲黑板划重点!
1.该问题类似于背包问题,但是不同的是给出的就是物品单位价值,因此不需要再计算物品单位质量的价值,这一点开始看错了,懵逼到后面才发现不对劲;
2.还是要注意输入要包括多个测试实例,可能现在练题还不是很多,应该熟练起来就不会犯这种低级错误了;
3.贪心策略:讲物品的单价降序排序,然后挑选单价最大的先放入背包中,尽可能多的把该物品放入背包。如果不能填满则背包当前可容纳物品容量即为剩余容量,再选择单价第二大的物品放入背包,相当于原问题的子问题。
4.向量vertor和sort函数的用法
vector<int> a(n); //动态分配长度为n的数组a #include<vector>
vector<vector<int> > a(n) //动态分配一维大小为n的二维数组
for(int i = 0;i < n;i++){
a[i].resize(3); //定义二维大小为3
}
a.push_back(i);
a.pop_back();
a,size(i);
a.resize(5); //改变一维大小
a[i].resize(3); //改变二维大小
sort(first,end); //默认为升序排序 #include<slgorithm>
sort(first,end,compare); //重写compare函数可实现降序排序或者其他自定义结构体的排序
bool conpare(int a,int b){ //降序排序
return a>b;
}
sort(a,a+n,compare); //a为长度为n的数组
sort(a.begin(),a.end(),compare); //a为vector向量
代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct T{
int p; //分别表示某种宝贝的单价和对应的体积
int m;
};
bool compare(T a,T b){ //宝贝单位体积的价值非降序排序
return (a.p>b.p);
}
int main(){
int n,v,i,sum;
cin>>v; //表示口袋的容量和宝贝的种类
while(v != 0){ //v为0的时候结束输入
sum = 0; //当前口袋中物品的总价值
cin>>n;
vector<T> a(n);
for(i = 0;i < n;i++){ //输入
cin>>a[i].p>>a[i].m;
}
sort(a.begin(),a.end(),compare); //宝贝单价非降序排序
for(i = 0;i < n && v > a[i].m;i++){
v -= a[i].m;
sum += a[i].m*a[i].p;
}
if(i < n){ //之前提交的时候显示错误,之后考虑特殊情况才AC
sum += v*a[i].p;
}
cout<<sum<<endl;
cin>>v;
}
return 0;
}
[HDU 2037]http://acm.hdu.edu.cn/showproblem.php?pid=2037
假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
Input
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),
分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0Sample Output
5
贪心算法的活动安排问题
代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Ti{
int s; //开始时间
int e; //结束时间
};
bool compare(Ti a,Ti b){ //按照节目的结束时间非降序排序,结束时间相同的按照开始时间较晚的排序
return (a.e < b.e || (a.e == b.e && a.s > b.s));
}
int main(){
int n,i,j,sum;
cin>>n; //喜欢看的节目的总数
while(n != 0){
sum = 1;
vector<Ti> a(n);
j = 0;
for(i = 0;i < n;i++){ //输入
cin>>a[i].s>>a[i].e;
}
sort(a.begin(),a.end(),compare); //排序
for(i = 1;i < n;i++){ //从活动i开始寻找与活动j相容的活动
if(a[i].s >= a[j].e){
j = i;
sum++;
}
}
cout<<sum<<endl;
cin>>n;
}
return 0;
}
[HDU 4310]http://acm.hdu.edu.cn/showproblem.php?pid=4310
When playing DotA with god-like rivals and pig-like team members, you have to face an embarrassing situation: All your teammates are killed, and you have to fight 1vN.
There are two key attributes for the heroes in the game, health point (HP) and damage per shot (DPS). Your hero has almost infinite HP, but only 1 DPS.
To simplify the problem, we assume the game is turn-based, but not real-time. In each round, you can choose one enemy hero to attack, and his HP will decrease by 1. While at the same time, all the lived enemy heroes will attack you, and your HP will decrease by the sum of their DPS. If one hero’s HP fall equal to (or below) zero, he will die after this round, and cannot attack you in the following rounds.Although your hero is undefeated, you want to choose best strategy to kill all the enemy heroes with minimum HP loss.
Input
The first line of each test case contains the number of enemy heroes N (1 <= N <= 20). Then N lines followed, each contains two integers DPSi and HPi, which are the DPS and HP for each hero. (1 <= DPSi, HPi <= 1000)Output
Output one line for each test, indicates the minimum HP loss.Sample Input
1
10 2
2
100 1
1 100Sample Output
20
201
对于全英文的题宝宝表示很是懵逼。只好将题目全都copy到百度翻译,特么的百度翻译还特别傻,高级句式都不会翻(笑cry)
浅显易懂翻译一下这道题:游戏中的英雄有两个很重要的属性,一个是生命值,一个是攻击值,当一个英雄生命值为0了,那它就go die了。你的英雄生命值是无限的,但你的攻击值只有1,你面对的敌人是一群攻击值和生命值都有限的英雄。在一个回合里,你只能选择一个英雄进行攻击,并且攻击造成的伤害能减少对方的生命值,同时对家的所有英雄也会对你攻击,现在你所要做的就是在已知对方生命值和攻击值的情况下,选择攻击的顺序以保证你的英雄受到最少的生命值损耗
贪心策略可通过数学方法计算得到
代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Dota{
int dps;
int hp;
int x;
}a[100];
bool compare(Dota a,Dota b){ //用贪心解决。血量少攻击高的要先消灭,所以以HP/DPS作为参数排序,即将所有的敌人根据DPS/HP从大到小排序,如果相等,则按HP从小到大排序
return (a.x>b.x);
// return (a.x>b.x || (a.x == b.x && a.hp<b.hp));
}
int main(){
int n,i;
long long sum,ans;
while(~scanf("%d",&n)){
sum = 0;
ans = 0;
for(i = 0;i < n;i++){ //输入
cin>>a[i].dps>>a[i].hp;
a[i].x = a[i].dps*1.0/a[i].hp;
sum += a[i].dps;
}
sort(a,a+n,compare);
for(i = 0;i < n;i++){
ans += a[i].hp*sum;
sum -= a[i].dps;
}
cout<<ans<<endl;
}
return 0;
标签:
原文地址:http://blog.csdn.net/a1128o/article/details/51906369