zoukankan      html  css  js  c++  java
  • P1311 选择客栈

    题意:一排n个客栈,每个有自己的色调值和花费

             现在有两个人要住进不同客栈,且这两个必须色调值相同

       并且在这两个客栈之间(包括这两个)必须至少有一个的花费<=p

       求方案数

    模拟大法好。。。。。。。。

    $O(n^3)$保TLE

    正解:       

    从1到n枚举,输入color和price的值,记录一个距离第二个客栈最近的咖啡厅价钱合理的客栈位置,用一个pos变量记录。

    开三个辅助数组,lst[i]表示最后一个以i为颜色的客栈的位置,tot[i]表示以i为颜色的客栈总数,lans[i]是一个临时数组,用来存储当前的方案数。

    可以这么想,当前枚举到一个客栈i,这个i是第二个客栈,那么显然第一个客栈一定在第二个客栈之前,编号必定是0~i-1之间的一个数。

    如果我发现枚举的时候在某一个客栈前面有一个价钱合理的咖啡厅,那么在这之前的任何一个同色客栈都是第一个客栈可以选的,那么统计一下数量,这就是当前的方案数。

    然后更新lst数组,更新ans,让tot[color]++,这样从左到右地推过来就好了。

    这个解法简化于暴力算法,暴力算法要循环三层,一层1客栈,二层2客栈,3层合理的位置,这样做显然不行,而我们做的就是去优化掉两层,而是从枚举2客栈出发推出1客栈的位置和所有可行方案,所以这样做是正确的。最后输出即可。

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define nmr 205050
    #define _ 0
    #define love_nmr 0
    #define olinr return
    int lst[nmr];
    int pos;
    int lans[nmr];
    int tot[nmr];
    int n;
    int k;
    int p;
    int ans;
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>k>>p;
        int color,value;
        for(int i=1;i<=n;i++)
        {
            cin>>color>>value;
            if(value<=p)
                pos=i;
            if(pos>=lst[color])
                lans[color]=tot[color];
            lst[color]=i;
            ans+=lans[color];
            tot[color]++;
        }
        cout<<ans;
        olinr ~~(0^_^0)+love_nmr;
    }
  • 相关阅读:
    List装form
    《Java设计模式》之调停者模式(Mediator)
    android 4.0 禁用系统home键
    最大权二分匹配
    hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
    【python】filter()
    【python】linux将python改为默认3.4版本
    【linux】VMware12.0安装
    【python】lxml-The E-factory
    【xml】python的lxml库使用
  • 原文地址:https://www.cnblogs.com/olinr/p/9514407.html
Copyright © 2011-2022 走看看