zoukankan      html  css  js  c++  java
  • 国王游戏【贪心+证明】

    感想:

    已经做了这么多到贪心题目,感觉大致的做法有以下几种。

    1.看到题目和以前做过的题目差不多或者类似,那么就把想法过度到以前做过的题上。

    2.直接分析,找出几种方法,进行类比。

    3。猜猜猜,假设猜测是正确,然后反证,得到的结果合理,那么贪心成立。


    -----------------------------------------------分界线---------------------------------------------------------

    以下这题,就是靠猜出来的。




    image

    假设以ai*bi从大到小排序是最优策略,那么我们假设其中有一对逆序对,也就是ai*bi > ai+1 * bi+1.

    接下来分析它交换之前,和交换之后的最大值的变化。

    交换之前和交换之后结果。

    image

    提取公因式就变成比较后乘上结果b[i]*b[i+1]就变成如下结果


    image

    又因为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 }
    追求吾之所爱
  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯VIP基础练习 矩形面积交
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
    在Linux中如何利用backtrace信息解决问题
  • 原文地址:https://www.cnblogs.com/rstz/p/14391032.html
Copyright © 2011-2022 走看看