【题解】sweet

题目描述

  为了防止糖果被小猫偷吃,John把他的糖果放在了很多的高台上,一个高台可以认为是一段平行于X轴的线段,并且高台的y坐标都是大于0的,每个高台都有左端点和高台的长度,每个高台都有糖果。所有的高台都不会重叠,也不会有公共端点。小猫一开始在地面上,他可以在地面上自由走动,然后他可以选择在地面上的任意一点跳到某个高台,然后可以吃掉该高台上的糖果,当小猫在某个高台X上时,它可以在该高台上自由的左右走动,然后它可以选择在X高台上的某点跳到高度大于或等于当前高台高度的那些高台。但小猫能跳到某高台必须满足一点:小猫的一次跳跃距离不能超过K,假设小猫从X点开始跳,如果Y高台离X点最近的距离小于等于K,那么小猫就可以跳到Y上,否则就不能跳到Y。

  现在有N个高台,给出每个高台的左端点的(x,y),和该高台的长度。

  给出每个高台上的糖果数量,给出K。 要你求小猫最多能吃多少糖果。(注意:高台上的糖果如果被吃了,那么下次小猫再到该高台时就没糖果吃了。)

 

输入格式

  第一行,两个整数,N和K,表示有N个高台和小猫一次跳跃的最大距离K。1≤N≤50,1≤K≤10000;

  接下来一行,有N个整数,空格分开,第i个整数表示第i个高台上拥有的糖果数量num。0≤num≤9999;

  接下来一行,有N个整数,空格分开,第i个整数表示第i个高台左端点的横坐标X。1≤X≤10000;

  接下来一行,有N个整数,空格分开,第i个整数表示第i个高台左端点的纵坐标Y。1≤Y≤10000。

  接下来一行,有N个整数,空格分开,第i个整数表示第i个高台的长度Len。1≤Len≤1000。

 

输出格式

  一行,输出小猫最多能吃多少糖果。

  给出两点之间的距离计算公式:点(x1,y1)、(x2,y2)之间的距离:

  dis=sqrt((x1-x2)×(x1-x2)+(y1-y2)×(y1-y2))

 

输入样例

6 2

1 2 3 4 3 5

1 1 1 4 5 5

1 3 4 1 2 3

2 1 1 2 1 1

输出样例

13

样例说明

Failed to load picture

  共有6个高台,如上图所示:每个高台上面的数字表示该高台上的糖果数量。小猫开始可以跳到高台1,吃掉一个糖果,然后移动到高台1的右端点,然后跳到高台4,吃掉4个糖果,然后跳到高台5,吃掉3个糖果,最后跳到高台6,吃掉5个糖果,共吃掉13个糖果)

题解

  毒瘤题,以后写思路,先看代码吧。

#include <iostream>
#include <algorithm>
#include <cmath>
#define MAXN 50

using namespace std;

int n, k;
struct node
{
    int num;
    int x, y;
    int len;
}a[MAXN];
bool cmp(node a, node b)
{
    if(a.y != b.y) return a.y < b.y;
    return a.x < b.x;
}
int f[MAXN];
int ans;

int main()
{
    cin >> n >> k;
    for(register int i = 0; i < n; i++) cin >> a[i].num;
    for(register int i = 0; i < n; i++) cin >> a[i].x;
    for(register int i = 0; i < n; i++) cin >> a[i].y;
    for(register int i = 0; i < n; i++) cin >> a[i].len;
    sort(a, a + n, cmp);
    for(register int i = 0, same = 0; i < n; i++)
    {
        for(register int  j = 0; j < i; j++) if(a[i].y  > a[j].y)
        {
            if((a[i].y - a[j].y) * (a[i].y - a[j].y) + (a[i].x - a[j].x - a[j].len) * (a[i].x - a[j].x - a[j].len) <= k * k)
            {
                f[i] = max(f[i], f[j]);
            }
            else if((a[i].y - a[j].y) * (a[i].y - a[j].y) + (a[j].x - a[i].x - a[i].len) * (a[j].x - a[i].x - a[i].len) <= k * k)
            {
                f[i] = max(f[i], f[j]);
            }
            else if((a[i].y - a[j].y) * (a[i].y - a[j].y) <= k * k
                 && (a[i].x >= a[j].x && a[i].x + a[i].len <= a[j].x + a[j].len
                 || a[j].x >= a[i].x && a[j].x + a[j].len <= a[i].x + a[i].len
                 || a[i].x < a[j].x && a[i].x + a[i].len >= a[j].x && a[i].x + a[i].len <= a[j].x + a[j].len
                 || a[j].x < a[i].x && a[j].x + a[j].len >= a[i].x && a[j].x + a[j].len <= a[i].x + a[i].len))
            {
                f[i] = max(f[i], f[j]);         
             }
        } 
        if(!f[i])
        {
            if(a[i].y * a[i].y <= k * k) f[i] = a[i].num;
            else continue;
        } 
        else
        {
            f[i] += a[i].num;
        }
        if(a[i + 1].y != a[i].y)
        {
            for(register int l = same, r = same + 1; r <= i; r++)
            {
                if((a[r].x - a[r - 1].x - a[r - 1].len) * (a[r].x - a[r - 1].x - a[r - 1].len) > k * k)
                {
                    for(register int j = l; j < r; j++)
                    {
                        for(register int jj = l; jj < r; jj++) if(j != jj)
                        {
                            f[j] += a[jj].num;
                        }
                    }
                    l = r;
                }
                else if(r == i)
                {
                    for(register int j = l; j <= r; j++)
                    {
                        for(register int jj = l; jj <= r; jj++) if(j != jj)
                        {
                            f[j] += a[jj].num;
                        }
                    }
                } 
            }
            same = i + 1;
        }
        ans = max(f[i], ans);
    }
    cout << ans;
    return 0;
} 
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10805505.html