国王游戏【贪心+证明】
感想:
已经做了这么多到贪心题目,感觉大致的做法有以下几种。
1.看到题目和以前做过的题目差不多或者类似,那么就把想法过度到以前做过的题上。
2.直接分析,找出几种方法,进行类比。
3。猜猜猜,假设猜测是正确,然后反证,得到的结果合理,那么贪心成立。
-----------------------------------------------分界线---------------------------------------------------------
以下这题,就是靠猜出来的。
假设以ai*bi从大到小排序是最优策略,那么我们假设其中有一对逆序对,也就是ai*bi > ai+1 * bi+1.
接下来分析它交换之前,和交换之后的最大值的变化。
交换之前和交换之后结果。
提取公因式就变成比较后乘上结果b[i]*b[i+1]就变成如下结果
又因为Ai*Bi >= Bi, 且Ai*Bi > Ai+1 * Bi+1 而且Ai+1 * Bi+1 >= Bi+1
所以就有 max(Bi, Ai+1 * Bi+1) < = Ai*Bi <= max(Bi+1,Ai*Bi);所以可得交换后的最大值不大于交换前的结果,可以得到当ai*bi > ai+1 * bi+1时交换时最好的策略,也就时保证局部最优解。
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <cstring> 5 using namespace std; 6 7 typedef pair<int, int> PII; 8 const int N = 1010; 9 10 int n; 11 PII p[N]; 12 vector<int> mul(vector<int>a, int b)//乘法 13 { 14 vector<int> c; 15 int t = 0; 16 for (int i = 0; i < a.size(); i ++ ) 17 { 18 t += a[i] * b; 19 c.push_back(t % 10); 20 t /= 10; 21 } 22 while (t) 23 { 24 c.push_back(t % 10); 25 t /= 10; 26 } 27 return c; 28 } 29 vector<int> div(vector<int> a, int b){ 30 vector<int> c; 31 int t = 0; 32 bool is_first = true; 33 for(int i = a.size() - 1; i >= 0; -- i){ 34 t = t*10 + a[i]; 35 int x = t / b; 36 if (!is_first || x){//防止前面出现零 37 is_first = false; 38 c.push_back(x); 39 } 40 t %= b; 41 } 42 reverse(c.begin(), c.end()); 43 return c; 44 } 45 vector<int> max_vec(vector<int> a, vector<int> b){ 46 if(a.size() > b.size()) return a; 47 if(a.size() < b.size()) return b; 48 if(vector<int>(a.rbegin(),a.rend()) > vector<int>(b.rbegin(), b.rend())) return a; 49 return b; 50 51 } 52 int main(){ 53 cin >> n; 54 for(int i = 0, a, b; i <= n; ++ i){ 55 cin >> a >> b; 56 p[i] = make_pair(a*b, a); 57 } 58 sort(p + 1, p + n + 1);//按a*b从小到大排序 59 vector<int> product(1, 1);//初始化容器加入一个元素为1 60 61 vector<int> res(1, 0);//用来存入最大值 62 for (int i = 0; i <= n; ++ i){ 63 if (i) res = max_vec(res, div(product, p[i].first/p[i].second));//自定义比较函数 64 product = mul(product, p[i].second);//乘积 65 } 66 for (int i = res.size() - 1; i >= 0; -- i) cout << res[i];//输出答案 67 cout << endl; 68 return 0; 69 }
追求吾之所爱