Magic Potions


题目描述:

一堆东西,每次拿出两个不同的东西合。要最终合出来的最多。并且要贪心的买12 13 14.。。1n 23.。。
http://codeforces.com/gym/100430/attachments/download/2418/20092010-summer-petrozavodsk-camp-andrew-stankevich-contest-36-asc-36-en.pdf

题解:

首先要保证总个数是最多的。怎么算总个数?求一下maxelement,然后sum-maxelement和max值比较,大中小对应情况。
其次要贪心的去取,那么我们最直接的:取12 取13.。。。可以取就一直取,如果取完算一下剩下的东西不能凑成原来的最优的结果的话,那么二分找到最大能够取得那个值。把它给取了。之后一旦发生这样的情况,说明已经到了后面的东西全部都和后面的最高值合并的特殊情况(这一点很重要),我们直接killit就好了。

另外也有一种其他方法:先贪心的合并,然后可能剩余一个有很多数量,再倒着拆已经合好的石头和这个剩余的合并。

重点:

(1)会算最大个数。
(2)按照题目中贪心。不能取的时候发现已经到了特殊情况。
(3)注意max=6 sum-max=7的情况。

代码:

1#include <iostream> 2#include <cstdio> 3#include <cstring> 4#include <string> 5#include <cmath> 6#include <ctype.h> 7#include <limits.h> 8#include <cstdlib> 9#include <algorithm> 10#include <vector> 11#include <queue> 12#include <map> 13#include <stack> 14#include <set> 15#include <bitset> 16#include <assert.h> 17#define CLR(a) memset(a, 0, sizeof(a)) 18#define REP(i, a, b) for(ll i = a;i < b;i++) 19typedef long long ll; 20 21using namespace std; 22 23const ll maxn = 1e5 + 100; 24struct info 25{ 26 ll a, b, num; 27 info(ll _a = 0, ll _b = 0, ll _num = 0) 28 { 29 a = _a; 30 b = _b; 31 num = _num; 32 } 33 bool operator < (const info & other) const 34 { 35 if(a == other.a) 36 { 37 return b < other.b; 38 } 39 return a < other.a; 40 } 41}; 42 43ll maxA[maxn], sum, maxa, maxi; 44ll a[maxn]; 45ll n; 46ll tot; 47vector<info> ans; 48vector<info> ansPro; 49void killIt(ll key) 50{ 51 for(ll i =1; i<=n; i++) 52 { 53 if(i != key && a[i] > 0 && a[key]>0) 54 { 55 ll sub = min(a[i], a[key]); 56 if(sub > 0) 57 { 58 59 60 61 ans.push_back(info(min(i, key), max(i, key), sub)); 62 a[i]-=sub; 63 a[key] -= sub; 64 } 65 } 66 } 67} 68 69void outPut() 70{ 71 sort(ans.begin(), ans.end()); 72// ll resSum = 0; 73// ansPro.clear(); 74// for(ll i = 0; i<ans.size(); i++) 75// { 76// if(ans[i].num != 0) 77// { 78// ansPro.push_back(ans[i]); 79// } 80// } 81// ans.clear(); 82// sort(ansPro.begin(), ansPro.end()); 83// for(ll i = 0; i<ansPro.size(); i++) 84// { 85// resSum += ansPro[i].num; 86// if(i!=0) 87// { 88// if(ansPro[i].a == ans[ans.size()-1].a && ansPro[i].b == ans[ans.size()-1].b) 89// { 90// ans[ans.size()-1].num += ansPro[i].num; 91// } 92// else 93// { 94// ans.push_back(ansPro[i]); 95// } 96// } 97// else 98// { 99// ans.push_back(ansPro[i]); 100// } 101// } 102 //ll tsum = 0; 103 ll tempAns = ans.size(); 104 printf("%I64d\n", tempAns); 105 for(ll i = 0; i<ans.size(); i++) 106 { 107 //tsum += ans[i].num; 108 printf("%I64d %I64d %I64d\n", ans[i].a, ans[i].b, ans[i].num); 109 } 110 //printf("%d -----\n", tsum); 111} 112ll gettot(ll mm, ll sum) 113{ 114 if(mm <= sum-mm) 115 return sum/2; 116 return sum-mm; 117} 118ll solve(ll &now1, ll &now2) 119{ 120 ll sub = min(a[now1], a[now2]); 121 ll tmpMax = max(a[now1],a[now2])-sub; 122 ll tmpSum = sum - sub*2; 123 tmpMax = max(maxA[now2+1], tmpMax); 124 ll tmptot = gettot(tmpMax, tmpSum); 125 126 if(tmptot+sub==tot) 127 { 128 129 130 131 sum = tmpSum; 132 a[now1]-=sub; 133 a[now2]-=sub; 134 tot -= sub; 135 ans.push_back(info(now1, now2, sub)); 136 if(a[now2]==0&&a[now1]==0) 137 { 138 now1=now2+1; 139 now2=now1+1; 140 } 141 else if(a[now2]==0) 142 { 143 now2++; 144 } 145 else 146 { 147 now1 = now2; 148 now2++; 149 } 150 return 1; 151 } 152 else 153 { 154 ll l = 0, r = sub; 155 while(l < r) 156 { 157 ll mid = (l+r)/2; 158 tmpSum = sum-2*mid; 159 tmpMax = max(a[now1],a[now2])-mid; 160 tmpMax = max(tmpMax, maxA[now2+1]); 161 tmptot = gettot(tmpMax, tmpSum); 162 if(tmptot+mid==tot) 163 { 164 l = mid+1; 165 } 166 else 167 { 168 r = mid; 169 } 170 } 171 r--; 172 if(r!=0) 173 ans.push_back(info(now1, now2, r)); 174 ll maxI = now1, maxA = a[now1]-r; 175 sum -= 2*r; 176 a[now1] -= r; 177 a[now2] -= r; 178 for(ll i = now2;i<=n;i++) 179 { 180 if(a[i]>maxA) 181 { 182 maxA = a[i]; 183 maxI = i; 184 } 185 } 186 killIt(maxI); 187 return 0; 188 } 189} 190void gao() 191{ 192 sum = 0; 193 for(ll i = 1; i<=n; i++) 194 { 195 sum += a[i]; 196 } 197 maxi = max_element(a+1, a+1+n)-a; 198 maxa = a[maxi]; 199 a[n+1] = 0; 200 maxA[n+1]=0; 201 for(ll i = n;i>=1;i--) 202 { 203 maxA[i]=max(maxA[i+1], a[i]); 204 } 205 ans.clear(); 206 if(!(maxa>=sum-maxa)) 207 { 208 tot = sum/2; 209 ll l = 1, r = 2; 210 while(r<=n) 211 { 212 ll flag = solve(l, r); 213 if(flag==0) 214 break; 215 } 216 } 217 else 218 { 219 killIt(maxi); 220 } 221 outPut(); 222} 223 224int main() 225{ 226 //freopen("11Kin.txt", "r", stdin); 227 //freopen("1out.txt", "w", stdout); 228 freopen("magic.in", "r", stdin); 229 freopen("magic.out", "w", stdout); 230 while(scanf("%I64d", &n)!=EOF) 231 { 232 for(ll i =1; i<=n; i++) 233 { 234 scanf("%I64d", &a[i]); 235 } 236 gao(); 237 } 238 return 0; 239}

本文分享 CSDN - ruclion。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )