BestCoder Round #71

65 篇文章 0 订阅
5 篇文章 0 订阅

此处有目录↑

HDU-5620 KK's Steel(数学)

http://acm.hdu.edu.cn/showproblem.php?pid=5620

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Our lovely KK has a difficult mathematical problem:he has a  N(1N1018)  meters steel,he will cut it into steels as many as possible,and he doesn't want any two of them be the same length or any three of them can form a triangle.
 

Input
The first line of the input file contains an integer  T(1T10) , which indicates the number of test cases.

Each test case contains one line including a integer  N(1N1018) ,indicating the length of the steel.
 

Output
For each test case, output one line, an integer represent the maxiumum number of steels he can cut it into.
 

Sample Input
  
  
1 6
 

Sample Output
  
  
3
Hint
1+2+3=6 but 1+2=3 They are all different and cannot make a triangle.

题目大意:对于一条长为N米的钢管,最多可以锯成几根小钢管,使得锯成的钢管互不相等且均不能围成三角形。

官方题解:只考虑最优切割策略:首先肯定是尽量的小即1、2,既要不相等,又不能构成三角形,即每次为当前数列中最大的两项的和,那么,构成的数列为1,2,3,5,8,......这样我们只要求最接近且小于等于N的Fibonacci数和的项数即可。

#include <cstdio>
#include <algorithm>

using namespace std;

int T;
long long f[90],n;

int main() {
    f[0]=0;
    f[1]=1;
    f[2]=2;
    for(int i=3;i<90;++i) {
        f[i]=f[i-1]+f[i-2];
        f[i-2]+=f[i-3];
    }
    scanf("%d",&T);
    while(T--) {
        scanf("%I64d",&n);
        printf("%d\n",upper_bound(f,f+86,n)-f-1);
    }
    return 0;
}


HDU-5621 KK's Point(数学)

http://acm.hdu.edu.cn/showproblem.php?pid=5621

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Our lovely KK has a difficult mathematical problem:He points  N(2N105)  points on a circle,there are all different.Now he's going to connect the  N  points with each other(There are no three lines in the circle to hand over a point.).KK wants to know how many points are there in the picture(Including the dots of boundary).
 

Input
The first line of the input file contains an integer  T(1T10) , which indicates the number of test cases.

For each test case, there are one lines,includes a integer  N(2N105) ,indicating the number of dots of the polygon.
 

Output
For each test case, there are one lines,includes a integer,indicating the number of the dots.
 

Sample Input
  
  
2 3 4
 

Sample Output
  
  
3 5
题目大意:他在一个圆上点下了互不重合的N个点,现在他要将这N个点两两相连(圆内没有三条线交于一个点的情况),KK想知道图形中一共有多少个交点(包括边界上的点)。


第一次div1都0题,还是太渣了

数学现在都渣成什么了,什么都不会,找递推还找错了;官方题解的方法还是太巧妙了,没看出来...

官方题解:先撇开边界上的点不管,那么所有的点都是有两条线所构成的,手算得出N=4的时候,能形成一个点,那么,我们只要知道n个点可以构成几个四边形即可,即求C(n,4),最后我们再把边界上的N个点加上,最后的结果是C(n,4)+n

#include <cstdio>

using namespace std;

int T,i,j;
long long n,a[2],b[2];

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%I64d",&n);
        a[0]=n*(n-1)/2;//计算C(n,4),防止溢出
        a[1]=(n-2)*(n-3)/2;
        b[0]=2;
        b[1]=3;
        for(i=0;i<2;++i)
            for(j=0;j<2;++j) {
                if(a[i]%b[j]==0) {
                    a[i]/=b[j];
                    b[j]=1;
                }
            }
        printf("%I64d\n",a[0]*a[1]+n);
    }
    return 0;
}

HDU-5623 KK's Number(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=5623

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)



Problem Description
Our lovely KK has a funny mathematical game:This game requires two people,There are  N(1N5104)  numbers,every time KK will take the numbers,first.Every time you can take any number of the numbers.Until the  N  number is taken.The minimum number of numbers is the score for each time.KK and the opponent's strategy is as much as possible to make their score minus the opponent's score more.In this case,How much is the final KK score minus the opponent's score?
 

Input
The first line of the input file contains an integer  T(1T10) , which indicates the number of test cases.
For each test case, there are two lines,in the first line is a integer  N(1N5104) ,the other line has  N  positive integers(no more than  109 ).
 

Output
For each test case, there are one lines,includes a integer,indicating the final KK's score minus the opponent's score.
 

Sample Input
  
  
1 3 1 3 1
 

Sample Output
  
  
2
Hint
Firstly KK take 3;and the opponent take 1,1,so the result is 2.

题目大意:这个游戏需要两个人,有N个数,每次KK都会先拿数。每次可以拿任意多个数,直到N个数被拿完。每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大。在这样的情况下,最终KK的得分减去对手的得分会是多少?


一点有思维难度的都做不出来,还各种贪心...


官方题解:显然,每个人的策略就是都会拿剩下的数中最大的某几个数,假如我们用f[i]表示当剩下i个数的时候先手得分-后手得分的最大值,那么得到f[i]=max(a[j+1]−f[j])(1<j≤i),但是这样做,是要超时的,我们不妨简单转换一下 f[i]=_max; _max=max(_max,a[i+1]-f[i]);

#include <cstdio>
#include <algorithm>

using namespace std;

int T,i,j,n,a[50005],dp[50005]={0};

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(i=1;i<=n;++i)
            scanf("%d",a+i);
        sort(a+1,a+n+1);
        for(i=1;i<=n;++i)
            dp[i]=max(dp[i-1],a[i]-dp[i-1]);//对于i,dp[i-1]是i-1个数后手-先手的最大值,a[i]-dp[i-1]则转化为先手-后手的值
        printf("%d\n",dp[n]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值