• 国王游戏【贪心+证明】


    感想:

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

    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 }
    追求吾之所爱
  • 相关阅读:
    Azure开发者任务之二:Cloud Service项目添加到ASP.Net Web中
    Azure开发者任务之一:解决Azure Storage Emulator初始化失败
    Configuring a Windows Azure Project
    How to manage the certificates in the PC
    在此声明我的博客已经搬到CSDN 中了
    http://www.cnblogs.com/Sniper-quay/archive/2011/06/22/2086636.html
    杂乱的UDPsocket
    socket下server端支持多客户端并发访问简单实现
    Qt 的udpSocket通信
    正则表达式
  • 原文地址:https://www.cnblogs.com/rstz/p/14391032.html
Copyright © 2020-2023  润新知