2018计蒜之道复赛 贝壳找房函数最值(贪心+优先队列)

贝壳找房函数最值

  • 35.12%
  •  1000ms
  •  262144K
 

贝壳找房的攻城狮最近在研究一次函数 f(x) = ax + bf(x)=ax+b。

现在有 nn 个一次函数,f_i(x) = a_ix+b_i,\ i = \{1 \mathellipsis n\}fi(x)=aix+bi, i={1n}。

容易发现,一次函数嵌套一次函数,还是一次函数。

 

\displaystyle f_{i}(f_{j}(x)) = a_{i} ( a_{j}x + b_{j}) + b_{i}fi(fj(x))=ai(ajx+bj)+bi

 

给定 xx,并且对于所有的 f_i(x)fi(x) 可以任意改变顺序嵌套函数,求 f(f(f(…f(x))…)f(f(f(f(x))) 的最大值。

输入数据

一个整数 T ( T \le 20 )T(T20) 代表数据组数。

每组数据:

第一行两个整数 n,\ xn, x 代表一共有 nn 个函数 ( 1 \le n \le 10000,\ 0 \le x \le 91n10000, 0x9) 。

第二行 nn 个整数代表 a_{i}ai , 1 \le a_{i} \le 91ai9 。

第三行 nn 个整数代表 b_{i}bi , 1 \le b_{i} \le 91bi9 。

输出数据

为了使问题简化,对于每组数据只需要输出最大值的个位即可。(比如函数的值可能是 1919 或者 2323 ,但最终应该输出的是 33)。

提示

对于第一组数据,有 66 种情况

3 \times (1 \times (2 \times 7 + 3) + 1) + 2 = 563×(1×(2×7+3)+1)+2=56

3 \times (2 \times (1 \times 7 + 1) + 3) + 2 = 593×(2×(1×7+1)+3)+2=59

1 \times (3 \times (2 \times 7 + 3) + 2) + 1 = 541×(3×(2×7+3)+2)+1=54

1 \times (2 \times (3 \times 7 + 2) + 3) + 1 = 501×(2×(3×7+2)+3)+1=50

2 \times (3 \times (1 \times 7 + 1) + 2) + 3 = 552×(3×(1×7+1)+2)+3=55

2 \times (1 \times (3 \times 7 + 2) + 1) + 3 = 512×(1×(3×7+2)+1)+3=51

所以输出 99

样例输入

2
3 7
3 1 2
2 1 3
3 2
9 1 2
9 1 2

样例输出

9
1

题目来源

2018 计蒜之道 复赛

 

 

https://blog.csdn.net/qq_41730082/article/details/80724298

正解:我们思考两个f的情况ax+b与cx+d,如此,有两种嵌套方式,分别为:a*(c*x+d)+b 与 c*(a*x+b)+d ,我们比较这两种嵌套方式的不同,总结得:a*(c*x+d)+b=ac*x+ad+b ; c*(a*x+b)+d=ac*x+bc+d,那么如果嵌套函数ff取第一式比较大的话,则ad+b>bc+d。说明第一式与第二式的不同不在于系数而在于ad+b与bc+d的大小,即,我们可以根据ai*bj+bi的大小对全体f进行排序。

两两之间的关系不是一劳永逸的,需要用动态变化的优先队列。

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Node{
    int a,b;
    friend bool operator<(Node a,Node b){
        return a.a*b.b+a.b>b.a*a.b+b.b;
    }
}a[10005];
priority_queue<Node> q;

int main()
{
    int t,n,x,i;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&x);
        for(i=1;i<=n;i++){
            scanf("%d",&a[i].a);
        }
        for(i=1;i<=n;i++){
            scanf("%d",&a[i].b);
            q.push(a[i]);
        }
        while(q.size()){
            x=q.top().a*x+q.top().b;
            x%=10;
            q.pop();
        }
        printf("%d\n",x);
    }
    return 0;
}

 

posted @ 2019-06-01 22:49  yzm10  阅读(484)  评论(0编辑  收藏  举报