当前位置:编程学习 > C/C++ >>

zoj Candies 贪心

根据题目可知3K位置的数量是可以直接确定的,并且n-2-3*k的也可以确定。所以只要这两部分不重合,答案就是确定的,或者有额外的位置是原来就已知,也是确定的。答案不确定的情况下,容易知道,有%3==1位置是同时取到最大值的,mod3==2也是同时取到最大值的。所以可以分别求出这两部分的最大值,然后O(1)回答。
 
 
#include <iostream>  
#include <cstdio>  
#include <cstring>  
using namespace std;  
const int maxn=1e5+9,inf=1e9;  
int a[maxn],sum[maxn];  
int max1[maxn],max2[maxn];  
int main()  
{  
//    freopen("in.txt","r",stdin);  
    int n;  
    while(scanf("%d",&n)!=EOF)  
    {  
        a[n+1]=a[0]=0;  
        for(int i=1;i<=n;i++)  
        scanf("%d",&a[i]);  
        for(int i=1;i<=n;i++)  
        scanf("%d",&sum[i]);  
  
        for(int i=3;i<=n;i+=3)  
        a[i]=sum[i-1]-(sum[i-2]-a[i-3]);  
  
        for(int i=n-2;i>=1;i-=3)  
        a[i]=sum[i+1]-(sum[i+2]-a[i+3]);  
  
        for(int i=1;i+2<=n;i++)  
        {  
            int tmp=0,txt,ss=0;  
            for(int j=0;j<=2;j++)  
            if(a[i+j]==-1) tmp++,txt=i+j;  
            else ss+=a[i+j];  
            if(tmp==1)  
            a[txt]=sum[i+1]-ss;  
        }  
  
        for(int i=n-2;i>=1;i--)  
        {  
            int tmp=0,txt,ss=0;  
            for(int j=0;j<=2;j++)  
            if(a[i+j]==-1) tmp++,txt=i+j;  
            else ss+=a[i+j];  
            if(tmp==1)  
            a[txt]=sum[i+1]-ss;  
        }  
  
        bool flag=true;  
        for(int i=1;i<=n;i++)  
        if(a[i]==-1) flag=false;  
  
        if(flag)  
        {  
            int m;  
            scanf("%d",&m);  
            for(int i=1,tmp;i<=m;i++)  
            {  
                scanf("%d",&tmp);  
                printf("%d\n",a[tmp+1]);  
            }  
        }  
        else  
        {  
            for(int i=1;i<=n;i++)  
            if(a[i]!=-1)  
            max1[i]=max2[i]=a[i];  
            else  
            max1[i]=max2[i]=-inf;  
  
            int min1=inf,min2=inf;  
            max1[1]=100000;  
            for(int i=1;i+2<=n;i++)  
            {  
                int tmp=0,txt,ss=0;  
                for(int j=0;j<=2;j++)  
                if(max1[i+j]==-inf) tmp++,txt=i+j;  
                else ss+=max1[i+j];  
                if(tmp==1)  
                {  
                    max1[txt]=sum[i+1]-ss;  
                    min1=min(min1,max1[txt]);  
                }  
            }  
  
            max2[2]=100000;  
            for(int i=1;i+2<=n;i++)  
            {  
                int tmp=0,txt,ss=0;  
                for(int j=0;j<=2;j++)  
                if(max2[i+j]==-inf) tmp++,txt=i+j;  
                else ss+=max2[i+j];  
                if(tmp==1)  
                {  
                    max2[txt]=sum[i+1]-ss;  
                    min2=min(min2,max2[txt]);  
                }  
            }  
  
            int m;  
            scanf("%d",&m);  
            for(int i=1,tmp;i<=m;i++)  
            {  
                scanf("%d",&tmp);  
                tmp++;  
                if(tmp%3==0)  
                printf("%d\n",a[tmp]);  
                else if(tmp%3==1)  
                printf("%d\n",max1[tmp]+min1);  
                else  
                printf("%d\n",max2[tmp]+min2);  
            }  
        }  
    }  
    return 0;  
}  

 

 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,