日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

NEFU OJ Problem1485 贪吃蛇大作战 题解

發(fā)布時間:2023/11/20 windows 32 coder
生活随笔 收集整理的這篇文章主要介紹了 NEFU OJ Problem1485 贪吃蛇大作战 题解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • Problem:F
  • Time Limit:1000ms
  • Memory Limit:65535K

題目

Description

貪吃蛇大家一定都玩過吧,現(xiàn)在宋哥也要玩這個游戲,最初的時候貪吃蛇從屏幕的左下角出發(fā),但是有一個非常不幸的事情,就是宋哥的游戲機(jī)的左鍵和下鍵壞掉了,這意味著什么?沒錯!他只能操控他的蛇向右或向上走了,假設(shè)屏幕被劃分為109*109的格子,而貪吃蛇從坐標(biāo)為(1,1)的格子出發(fā),每次操作可以從坐標(biāo)為(x,y)的格子前往坐標(biāo)為(x+1,y)或(x,y+1)的格子,在所有格子中有一些格子中有一些食物,宋哥現(xiàn)在想知道,他的貪吃蛇最多能吃到多少食物呢?

Input

輸入的第一行包含一個數(shù)字T(1<=T<=10),代表數(shù)據(jù)組數(shù),之后的每組數(shù)據(jù)的每一行包含一個數(shù)字n (1<=n<=1000),代表有食物的格子數(shù)量,之后的n行每一行包含三個數(shù)字xi(1<=xi<=109),yi(1&lt;=xi&lt;=109),pi(1<=xi<=10^6),分別代表格子的坐標(biāo)和在這個格子里的食物數(shù)量。

Output

輸出T行,第i行為第i組數(shù)據(jù)的答案。

Sample Input

2
3
1 1 1
2 2 2
3 3 3
3
1 3 1
2 2 2
3 1 3

Sample Output

6
3

Hint

Source

MGH

思路

看起來像很經(jīng)典的dp問題,但是區(qū)別是點(diǎn)很稀疏,只有1e3的點(diǎn),卻有1e9*1e9的棋盤,考慮將點(diǎn)位置重新緊密排布, 建立一個映射將稀疏點(diǎn)集\(S\)映射到緊密點(diǎn)集\(P'\)\(f:\{P_i = (X_i,Y_i)\in S\}\rightarrow \{P'_i=(X'_i,Y'_i)\in S'\}\)使得\(S'\)方便使用dp。

需要保證重新排布后性質(zhì)不變,分析后得知需要滿足保持原本的橫縱坐標(biāo)的大小關(guān)系即

\[\forall P_i, P_j\in S \left\{ \begin{array}{c} x_i < x_j \rightarrow x'_i < x'_j\\ x_i = x_j \rightarrow x'_i = x'_j\\ x_i > x_j \rightarrow x'_i > x'_j\\ \end{array} \right. \]

\[\forall P_i, P_j\in S \left\{ \begin{array}{c} y_i < y_j \rightarrow y'_i < y'_j\\ y_i = y_j \rightarrow y'_i = y'_j\\ y_i > y_j \rightarrow y'_i > y'_j\\ \end{array} \right. \]

如下圖所示方法,刪除所有空行和空列可以實(shí)現(xiàn)。

算法實(shí)現(xiàn)

  1. \(x\)坐標(biāo)由小到大排序
  2. 對于每個點(diǎn)遍歷從0開始分配新的\(x'\)坐標(biāo),如果某個點(diǎn)\(x\)坐標(biāo)與上一個點(diǎn)相同,則分配相同的\(x'\)坐標(biāo),而不遞增\(x'\)

之后再對\(y\)坐標(biāo)進(jìn)行同樣的操作。

完成后對\(S'\)點(diǎn)集進(jìn)行DP即可

代碼如下

#include <bits/stdc++.h>

using namespace std;

struct Food
{
    int x, y, v, _x, _y;//_x和_y代表映射后坐標(biāo)
} food[1020];

int mp[1020][1020], dp[1020][1020];

bool Cmp1(Food f1, Food f2)//x排序
{
    return f1.x < f2.x;
}
bool Cmp2(Food f1, Food f2)//y排序
{
    return f1.y < f2.y;
}

int Find(int x, int y)//Dp
{
    if(dp[x][y] != -1)
        return dp[x][y];

    int res = 0;
    if(x-1 >= 0)
        res = max(res, Find(x-1,y));
    if(y-1 >= 0)
        res = max(res, Find(x,y-1));
    return dp[x][y] = res + mp[x][y];
}
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i ++)
            scanf("%d%d%d", &food[i].x, &food[i].y, &food[i].v);

        //x排序并分配新坐標(biāo)
        sort(food, food+n, Cmp1);
        int ind_x = 1;
        food[0]._x = 1;
        for (int i = 1; i < n; i ++)
            if(food[i].x == food[i-1].x)
                food[i]._x = ind_x;
            else
                food[i]._x = ++ind_x;

        //y排序并分配新坐標(biāo)
        sort(food, food+n, Cmp2);
        int ind_y = 1;
        food[0]._y = 1;
        for (int i = 1; i < n; i ++)
            if(food[i].y == food[i-1].y)
                food[i]._y = ind_y;
            else
                food[i]._y = ++ind_y;


        //普通DP過程
        for (int i = 0; i <= 1000; i ++)
            for (int j = 0; j <= 1000; j ++)
                mp[i][j] = 0;

        for (int i = 0; i < n; i ++)
            mp[food[i]._x][food[i]._y] = food[i].v;

        for (int i = 0; i <= ind_x; i ++)
            for (int j = 0; j <= ind_y; j ++)
                dp[i][j] = -1;

        dp[0][0] = 0;

        cout << Find(ind_x,ind_y) << endl;
    }
    return 0;
}

總結(jié)

以上是生活随笔為你收集整理的NEFU OJ Problem1485 贪吃蛇大作战 题解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。