腾讯马拉松之 湫湫系列故事——消灭兔子
2014-02-26 15:45
274 查看
湫湫系列故事——消灭兔子
题目链接:Click Here~
题目分析:
题目要求,用最小的花费杀死所有的Rabbits。可以从题意就推测出这是一道贪心题,但是不是普通的做法就可以过了,因为数据太大,所以要用到一些数据结构。
本题可以用多种算法解题。好像本人暂时知道的有三种,贪心+优先队列,贪心+STL,线段树。我是用贪心+STL做的。如果,对其他做法感兴趣的话可以自己百度。
算法思路分析:
从贪心的角度分析,我们知道要想最后的花费最少。肯定要每一支箭尽最大的可能去射杀血量最大的兔子,且这支箭的花费又要尽最大可能的小。所以,从这两条要求中我们就可以知道,要先对每只箭的价值从小到大排序,使得尽可能的用价值较小的箭去射杀血量尽可能大的兔子。可以看出朴素的方法在1e5的数据小肯定超时。所以,这里我就想到了将兔子的血量先排序。然后,用排完序的价值中的伤害值去查找可以射杀的最大血量的兔子是多少。每次找到一只可以射杀的兔子后,就将这只兔子删除。这种方法查找下去一定会使花费最小。不理解的要自己好好想想。然后,又偷偷的学习了一下STL中的multiset<>的用法。最后,细节部分就自己看下面的代码吧。第三份代码是根据别人提供的思路,我自己写了一遍,一提交居然是171s。上排行榜前几了!!!!太无语了-_-
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
struct Rabbit{
int hurt,price;
bool operator < (const Rabbit &a)const{
return price < a.price;
}
}list
;
multiset<int> S;
multiset<int>::iterator it;
void Init(int n,int m)
{
int hp;
S.clear();
for(int i = 0;i < n;++i){
scanf("%d",&hp);
S.insert(-hp);
}
for(int i = 0;i < m;++i)
scanf("%d",&list[i].hurt);
for(int i = 0;i < m;++i)
scanf("%d",&list[i].price);
sort(list,list+m);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
Init(n,m);
int cnt = 0;
__int64 ans = 0;
for(int i = 0;i<m&&cnt<n;++i){
it = S.lower_bound(-list[i].hurt);
if(it != S.end()){
cnt++;
ans += list[i].price; // cout<<"price = " <<list[i].price<<endl;
S.erase(it);
}
}
if(cnt == n)
printf("%I64d\n",ans);
else
printf("No\n");
}
return 0;
}
优先队列版:
题目链接:Click Here~
题目分析:
题目要求,用最小的花费杀死所有的Rabbits。可以从题意就推测出这是一道贪心题,但是不是普通的做法就可以过了,因为数据太大,所以要用到一些数据结构。
本题可以用多种算法解题。好像本人暂时知道的有三种,贪心+优先队列,贪心+STL,线段树。我是用贪心+STL做的。如果,对其他做法感兴趣的话可以自己百度。
算法思路分析:
从贪心的角度分析,我们知道要想最后的花费最少。肯定要每一支箭尽最大的可能去射杀血量最大的兔子,且这支箭的花费又要尽最大可能的小。所以,从这两条要求中我们就可以知道,要先对每只箭的价值从小到大排序,使得尽可能的用价值较小的箭去射杀血量尽可能大的兔子。可以看出朴素的方法在1e5的数据小肯定超时。所以,这里我就想到了将兔子的血量先排序。然后,用排完序的价值中的伤害值去查找可以射杀的最大血量的兔子是多少。每次找到一只可以射杀的兔子后,就将这只兔子删除。这种方法查找下去一定会使花费最小。不理解的要自己好好想想。然后,又偷偷的学习了一下STL中的multiset<>的用法。最后,细节部分就自己看下面的代码吧。第三份代码是根据别人提供的思路,我自己写了一遍,一提交居然是171s。上排行榜前几了!!!!太无语了-_-
#include <iostream> #include <algorithm> #include <set> #include <vector> #include <cstdio> #include <cstring> using namespace std; const int N = 1e5 + 10; struct Rabbit{ int hurt,price; bool operator < (const Rabbit &a)const{ return price < a.price; } }list ; multiset<int> S; multiset<int>::iterator it; void Init(int n,int m) { int hp; S.clear(); for(int i = 0;i < n;++i){ //每只兔子的血量 scanf("%d",&hp); S.insert(hp); } for(int i = 0;i < m;++i) //第i支箭的伤害值 scanf("%d",&list[i].hurt); for(int i = 0;i < m;++i) scanf("%d",&list[i].price); //第i支箭的价值 sort(list,list+m); } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { Init(n,m); int cnt = 0; __int64 ans = 0; for(int i = 0;i<m&&cnt<n;++i){ it = S.upper_bound(list[i].hurt); if(it != S.begin()){ cnt++; ans += list[i].price; S.erase(--it); //可以射杀兔子的最小花费 } } if(cnt == n) printf("%I64d\n",ans); else printf("No\n"); } return 0; }
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
struct Rabbit{
int hurt,price;
bool operator < (const Rabbit &a)const{
return price < a.price;
}
}list
;
multiset<int> S;
multiset<int>::iterator it;
void Init(int n,int m)
{
int hp;
S.clear();
for(int i = 0;i < n;++i){
scanf("%d",&hp);
S.insert(-hp);
}
for(int i = 0;i < m;++i)
scanf("%d",&list[i].hurt);
for(int i = 0;i < m;++i)
scanf("%d",&list[i].price);
sort(list,list+m);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
Init(n,m);
int cnt = 0;
__int64 ans = 0;
for(int i = 0;i<m&&cnt<n;++i){
it = S.lower_bound(-list[i].hurt);
if(it != S.end()){
cnt++;
ans += list[i].price; // cout<<"price = " <<list[i].price<<endl;
S.erase(it);
}
}
if(cnt == n)
printf("%I64d\n",ans);
else
printf("No\n");
}
return 0;
}
优先队列版:
#include <iostream> #include <algorithm> #include <cstdio> #include <vector> #include <queue> #include <cstring> using namespace std; typedef __int64 LL; const int N = 1e5 + 5; struct Rabbit{ int hurt,price; bool operator <(const Rabbit &a)const{ return price > a.price; } }rab ; bool cmp1(int a,int b) //兔子的血量排序 { return a > b; } bool cmp2(Rabbit &a,Rabbit &b) //箭的伤害值排序 { return a.hurt < b.hurt; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int hp; vector<int> ive; vector<int>::iterator it; priority_queue <Rabbit> Q; for(int i = 1;i <= n;++i){ scanf("%d",&hp); ive.push_back(hp); } for(int i = 1;i <= m;++i) scanf("%d",&rab[i].hurt); for(int i = 1;i <= m;++i) scanf("%d",&rab[i].price); sort(ive.begin(),ive.end(),cmp1); sort(rab+1,rab+m+1,cmp2); LL ans = 0; int k = m; for(it = ive.begin();it != ive.end();++it){ while(k&&(*it) <= rab[k].hurt){ //将所有可以杀死第i只兔子的箭都压入到队列中 Q.push(rab[k]); k--; } if(Q.empty()) break; Rabbit tmp = Q.top(); //获取最小花费的箭 Q.pop(); ans += tmp.price; } if(it == ive.end()) printf("%I64d\n",ans); else printf("No\n"); } return 0; }
相关文章推荐
- 腾讯马拉松复赛第三场,HDOJ-4544 - 湫湫系列故事——消灭兔子
- HDU - 4544 湫湫系列故事――消灭兔子 2013腾讯编程马拉松复赛第三场
- hdu 4544 湫湫系列故事——消灭兔子
- HDU 4544 湫湫系列故事——消灭兔子
- 2013腾讯编程马拉松初赛第一场(3月21日)湫湫系列故事——减肥记I
- 【HDOJ】4544 湫湫系列故事——消灭兔子
- hdu 4544 湫湫系列故事——消灭兔子(优先队列)
- 杭电OJ4544 湫湫系列故事——消灭兔子(优先队列过)
- HDU-4544-湫湫系列故事——消灭兔子
- 2013腾讯编程马拉松初赛第一场(3月21日) 湫湫系列故事——减肥记I hdu 4508--- 完全背包
- 2013腾讯编程马拉松初赛第〇场(HDU 4503) 湫湫系列故事——植树节
- HDU 4544 湫湫系列故事——消灭兔子
- hdu 4544 湫湫系列故事——消灭兔子 贪心+sbt
- 湫湫系列故事——消灭兔子
- HDU 4544|湫湫系列故事——消灭兔子|平衡树|优先队列|STL
- 2013腾讯编程马拉松初赛第〇场(HDU 4503) 湫湫系列故事——植树节
- hdu 4544 湫湫系列故事——消灭兔子 优先队列+贪心
- HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松)
- HDU - 4544 湫湫系列故事——消灭兔子 贪心+优先队列
- hdu 4544 湫湫系列故事——消灭兔子