HDU 5171GTY's birthday gift

来源:互联网 发布:建筑能耗模拟软件 编辑:程序博客网 时间:2024/05/29 03:56

GTY's birthday gift

点击打开题目链接

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 585    Accepted Submission(s): 103


Problem Description
FFZ's birthday is coming. GTY wants to give a gift to ZZF. He asked his gay friends what he should give to ZZF. One of them said, 'Nothing is more interesting than a number multiset.' So GTY decided to make a multiset for ZZF. Multiset can contain elements with same values. Because GTY wants to finish the gift as soon as possible, he will use JURUO magic. It allows him to choose two numbers a and b( a,b \in S ), and add a + b to the multiset. GTY can use the magic for k times, and he wants the sum of the multiset is maximum, because the larger the sum is, the happier FFZ will be. You need to help him calculate the maximum sum of the multiset.
 
Input
Multi test cases (about 3) . The first line contains two integers n and k ( 2\leq n \leq 100000 , 1 \leq k \leq 1000000000 ). The second line contains n elements a_i ( 1\leq a_i \leq 100000)separated by spaces , indicating the multiset S .
 
Output
For each case , print the maximum sum of the multiset (mod~10000007).
 
Sample Input
3 23 6 2
Sample Output
35
中文题面:
GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 ,现在GTY想最大化可重集的和,这个工作就交给你了。  注:可重集是指可以包含多个相同元素的集合
先对于给定的数列排序,每次找最大的两个数,例如样例,
2,3,6
第一次加入,
2,3,6,(6+3),
第二次加入:2,3,6,(6+3),(6+3+6)
最后和为2+3+6+6+3+6+3+6=11+9+15=35;
设sum为数列的和,S[k]为斐波那契数列的前n项和
ans=(sum+(S[k+1]-1)*a[n-1]+S[k]*a[n-2])%mod;
斐波那契数列有条性质:S[k]=F[k+2]-1,(其中F[0]=0,F[1]=F[2]=1)
第一种:打表,注意到取摸,那么斐波那契数列取模,肯定是有循环的;
代码:
#include <iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>#include<stdlib.h>#include<string>#include<map>#include<set>#include<queue>#include<stack>#include<math.h>#define inf 0x3f3f3f3f#define eps 1e-5#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define mod 10000007#define N 4995200using namespace std;long long int F[N];int init(){    F[0]=F[1]=1;    for(int i=2;i<N;i++)    {        F[i]=(F[i-1]+F[i-2])%mod;        if(F[i]==F[1]&&F[i-1]==F[0])//出现循环跳出        {            return i;            break;        }    }    return N;}int a[N];int cmp(const void *a,const void *b){    return *(int *)a-*(int *)b;}int main(){    int n,k;    long long sum;    int t=init(),i;    while(~scanf("%d%d",&n,&k))    {        sum=0;        for(i=0;i<n;i++)        {            scanf("%d",&a[i]);            sum=(sum+a[i])%mod;        }        qsort(a,n,sizeof(a[0]),cmp);        long long int max1=a[n-1],max2=a[n-2];        sum=(sum+(F[(k+2)%(t-1)]-2)*max1%mod)%mod;///注意:这里的t比循环要大一个,所以减去1;        sum=(sum+(F[(k+1)%(t-1)]-1)*max2%mod)%mod;        printf("%I64d\n",sum);    }    return 0;}

第二种:矩阵快速幂,把第一项看做a[n-2],第二项看做a[n-1],然后求这个类斐波那契数列的前k项和;
然后求矩阵快速幂即可;
代码:
#include <iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>#include<stdlib.h>#include<string>#include<map>#include<set>#include<queue>#include<stack>#include<math.h>#define inf 0x3f3f3f3f#define eps 1e-5#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define N 3#define mod 10000007#define M 1000010using namespace std;struct Matrix{    long long int m[N][N];    friend Matrix operator*(Matrix &a,Matrix &b)    {        int i,j,k;        Matrix c;        memset(c.m,0,sizeof(c.m));        for(i=0; i<N; i++)        {            for(j=0; j<N; j++)            {                for(k=0; k<N; k++)                {                    if(!b.m[k][j]||!b.m[i][k])continue;                    c.m[i][j]+=(a.m[i][k]*b.m[k][j]+mod)%mod;                    c.m[i][j]%=mod;                }            }        }        return c;    }    friend Matrix operator^(Matrix a,int n)    {        Matrix b;        memset(b.m,0,sizeof(b.m));        for(int i=0; i<N; i++)b.m[i][i]=1;        while(n)        {            if(n&1) b=b*a;            a=a*a;            n/=2;        }        return b;    }};int cmp(const void *a,const void *b){    return *(int *)a-*(int *)b;}int a[M];int main(){    int n,k,i;    long long sum;    while(~scanf("%d%d",&n,&k))    {        sum=0;        for(i=0; i<n; i++)        {            scanf("%d",&a[i]);            sum=(sum+a[i])%mod;        }        qsort(a,n,sizeof(a[0]),cmp);        Matrix ans,b;        ans.m[0][0]=1,ans.m[0][1]=1,ans.m[0][2]=1;        ans.m[1][0]=0,ans.m[1][1]=1,ans.m[1][2]=1;        ans.m[2][0]=0,ans.m[2][1]=1,ans.m[2][2]=0;        ans=ans^k;        printf("%I64d\n",((ans.m[0][0]+ans.m[0][1]-1)*a[n-1]+ans.m[0][2]*a[n-2]+sum)%mod);    }    return 0;}



0 0
原创粉丝点击