1. 程式人生 > >51nod 1191 消滅兔子

51nod 1191 消滅兔子

splay sum == pan chan .html != std sed

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1191

有N只兔子,每只有一個血量B[i],需要用箭殺死免子。有M種不同類型的箭可以選擇,每種箭對兔子的傷害值分別為D[i],價格為P[i](1 <= i <= M)。假設每種箭只能使用一次,每只免子也只能被射一次,計算要消滅地圖上的所有兔子最少需要多少Q幣。如不能殺死所有兔子,請輸出No Solution。 特別說明:1、當箭的傷害值大於等於兔子的血量時,能將兔子殺死;2、血量B[i],箭的傷害值D[i],箭的價格P[i],均小於等於100000。 這個題很容易想到貪心,也就是每只兔子要被能夠殺死它的價格最便宜且沒有被用過的箭殺死,於是我們就可以先給兔子血量從大到小排個序,然後維護一個優先隊列,存放能夠殺死當前兔子的箭,每次取最便宜的即可(好像基本上百度上都是這個做法) 但是本垃圾的代碼使用了線段樹,線段樹維護血量在這個區間的兔子有多少,然後按價格給箭排序,每只箭殺死它能夠殺死的的兔子中血量最大的 技術分享
 1 #include<string>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdio>
 7 #include<queue>
 8 #include<vector>
 9 using namespace std;
10 typedef long long ll;
11 const int MAXN=100005;
12 typedef struct
node 13 { 14 int atk,cost; 15 node(){} 16 node(int a,int b){atk=a,cost=b;} 17 friend bool operator<(node a,node b){return a.cost<b.cost;} 18 }node ; 19 node arr[50005]; 20 int tree[400005]; 21 int query(int root,int l,int r,int val) 22 { 23 if(l==r)return l; 24 int mid=(l+r)/2;
25 if(val>=mid+1&&tree[root*2+2]>=1) 26 { 27 int tmp=query(root*2+2,mid+1,r,val); 28 if(tmp!=-1)return tmp; 29 } 30 if(tree[root*2+1]>=1)return query(root*2+1,l,mid,val); 31 return -1; 32 } 33 void changeval(int root,int l,int r,int pos,int val) 34 { 35 if(l==r) 36 { 37 tree[root]+=val; 38 return ; 39 } 40 int mid=(l+r)/2; 41 if(pos<=mid)changeval(root*2+1,l,mid,pos,val); 42 else changeval(root*2+2,mid+1,r,pos,val); 43 tree[root]=tree[root*2+1]+tree[root*2+2]; 44 } 45 int main() 46 { 47 int i,j; 48 int n,m; 49 scanf("%d%d",&n,&m); 50 if(n>m) 51 { 52 printf("No Solution\n"); 53 return 0; 54 } 55 memset(tree,0,sizeof(tree)); 56 for(i=0;i<n;i++) 57 { 58 int a; 59 scanf("%d",&a); 60 changeval(1,1,MAXN,a,1); 61 } 62 for(i=0;i<m;i++)scanf("%d%d",&arr[i].atk,&arr[i].cost); 63 sort(arr,arr+m); 64 ll sum=0; 65 int ans=0; 66 for(i=0;i<m;i++) 67 { 68 int pos=query(1,1,MAXN,arr[i].atk); 69 if(pos==-1)continue; 70 ans++; 71 sum+=arr[i].cost; 72 changeval(1,1,MAXN,pos,-1); 73 if(ans>=n)break; 74 } 75 if(ans<n) 76 { 77 printf("No Solution\n"); 78 } 79 else 80 { 81 printf("%lld\n",sum); 82 } 83 return 0; 84 } 85 86 /* 87 5 8 88 1 7 6 4 9 89 9 1 90 6 4 91 4 3 92 3 6 93 6 5 94 2 3 95 5 1 96 8 7 97 */
View Code

51nod 1191 消滅兔子