补充的算法题

题目描述

题目是这样的:
“一个双人游戏是这样玩的:给定一个非负正整数序列,你每次只能从序列头部取1个、2个或者3
个数,取到的整数累加到你的得分上。两个人轮流如此,知道取完所有整数。每个人都足够聪明,
每个人的目的是最大化自己的得分,请问第一个人最终的得分是多少?

输入格式
多组数据,每组数据第一行是一个正整数n,表示序列中数的个数。(n<=100000)
第二行是n个空格分隔的非负整数,表示每个数,每个数不超过1000000000。
输出格式
表示你的最终得分”

实现代码如下:



#include<stdio.h>
#include<stdlib.h>

int *arr; 
//返回a,b,c中的最大值。 
int max(int a,int b,int c){
    if(a>=b&&a>=c)
        return a;
    else if(b>=c)
        return b;
    else
        return c; 
}
//计算数组从下标index开始剩余元素的长度 
int sum(int index,int len){
    int sum=0;
    for(int i=index;i<len;i++){
        sum+=arr[i];
    }
    return sum;
}
//返回的是第二个人的得分。
//有个逻辑要清楚:第一次你是firstPoint,第二次你就是secondPoint,计算这两者的最大值才是你的得分。 
int maxPoint(int begin,int len){
    int length=len-begin;
    int firstPoint=0;//第一个选手先来 
    int secondPoint=0;
    //以下三个变量用来表示取一张牌、二张牌和三张牌的最大结果。 
    int onePoint=0;
    int twoPoint=0;
    int threePoint=0; 
    if(length<=3){
        //将剩余的全部取走,使其达到最大
        for(int i=begin;i<len;i++){
            firstPoint+=arr[i];
            return 0;
        } 
    }
    else if(length==4){
        firstPoint=arr[begin]+arr[begin+1]+arr[begin+2];
        secondPoint=arr[len-1];
        return secondPoint;
    }
    else{//还有很多元素
        onePoint=arr[begin]+maxPoint(begin+1,len);
        twoPoint=arr[begin]+arr[begin+1]+maxPoint(begin+2,len);
        threePoint=arr[begin]+arr[begin+1]+arr[begin+2]+maxPoint(begin+3,len);
        //在onePoint /twoPoint/threePoint 中取最大值
        firstPoint=max(onePoint,twoPoint,threePoint); 
        secondPoint=sum(begin,len)-firstPoint;
        return  secondPoint;
    }

}
int main(void){
    int k;
    while(scanf("%d",&k)!=EOF&&k>0){
        arr=(int *)malloc(k*sizeof(int));
        if(arr==NULL){
            exit(EXIT_FAILURE);
        }
        for(int i=0;i<k;i++)
            scanf("%d",arr+i);
        int result=sum(0,k)-maxPoint(0,k);//
        printf("%d\n",result);
    }
} 




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值