[2014-2015 ACM-ICPC, NEERC Subregional Contest]解题报告



A. Nasta Rabbara

B. Colored Blankets

C. Component Tree

D. Data Center

这个题

E. Election of a Mayor

F. Ilya Muromets

题目大意:给你一个长度为n的序列,要你从中找两个互不重叠的区间,且每个区间长度不能超过k,求这两个区间中元素和的最大值

比赛时被D和I题蒙蔽了,以为此题也是贪心,结果做了半天tried but failed,实际上此题是一道很巧妙的前缀和+DP题,令Dec[i]=以第i个元素为终点,长度为k的区间和,DP[i][j]=前i个头砍j次得到的最大分数,那么我们可以得到一个DP方程:

1、dp[i][1]=Dec[i],i∈[1,k]

2、dp[i][1]=max(dp[i-1][1],Dec[i]); //前i个头砍1次的计算:要么第i个头不砍,要么要砍第i个头
      dp[i][2]=max(dp[i-1][2],Dec[i]+dp[i-k][1]); ////前i个头砍2次的计算:要么第i个头不砍,要么要砍第i个头

      i∈(k,n]

就这么简单,但是比赛时居然把这题想复杂了,真的是很令人痛心

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 201000

using namespace std;

int f,dp[MAXN][4]; //dp[i][j]=前i个头砍j次的最大和
int Dec[MAXN]; //Dec[i]=以第i号元素截止的长度为k的区间和
int sum[MAXN];

int max(int a,int b)
{
    if(a>b) return a;
    return b;
}

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        memset(sum,0,sizeof(sum));
        memset(dp,0,sizeof(dp));
        memset(Dec,0,sizeof(Dec));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&f);
            sum[i]=sum[i-1]+f;
        }
        if(n<=k*2)
        {
            printf("%d\n",sum[n]); //此时显然可以把所有的头都砍下来
            continue;
        }
        dp[1][0]=0;
        dp[1][1]=sum[1];
        for(int i=1;i<=k;i++) Dec[i]=sum[i];
        for(int i=k+1;i<=n;i++)
            Dec[i]=sum[i]-sum[i-k];
        for(int i=1;i<=k;i++)
            dp[i][1]=Dec[i];
        for(int i=k+1;i<=n;i++)
        {
            dp[i][1]=max(dp[i-1][1],Dec[i]); //前i个头砍1次的计算:要么第i个头不砍,要么要砍第i个头
            dp[i][2]=max(dp[i-1][2],Dec[i]+dp[i-k][1]); ////前i个头砍2次的计算:要么第i个头不砍,要么要砍第i个头
        }
        printf("%d\n",dp[n][2]);
    }
    return 0;
}


G. FacePalm Accounting

H. Minimal Agapov Code

I. Sale in GameStore

本次比赛中最水的题,题目大意是好朋友可以帮你为游戏买单,但是他替你付的钱必须小于等于你自己掏腰包花的钱,问你最多能买多少游戏。很明显这是个贪心,我们只需要买最贵的那个游戏,然后按价格从小到大选择游戏让朋友替你买单就OK了

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

#define MAXN 2010

using namespace std;

int p[MAXN];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i]);
        sort(p+1,p+n+1);
        int all=p[n],sum=0,cnt=1;
        for(int i=1;i<n;i++)
        {
            if(sum+p[i]<=all)
            {
                sum+=p[i];
                cnt++;
            }
            else break;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

J. Getting Ready for VIPC

K. Treeland

L. Useful Roads

M. Variable Shadowing

你可能感兴趣的:([2014-2015 ACM-ICPC, NEERC Subregional Contest]解题报告)