シール枚
質問リンク
問題に明確な条件を以下のように整理する.題では,現在座標(a,b)のシールを外すと,左(a,b−1),右(a,b+1),下(a+1,b),上(a−1,b)を取り除くことができない. シールを外さなくてもいいです. n<=10000を考慮するとbrute forceはタイムアウトします.そのため、私たちは大きな問題を一部の問題に分けて考えるべきだ.
大きな問題は「何枚かのシールを引き裂いても最大点数がもらえる」ということです.これを「現在の座標(x,y)に格納されている最大スコア」という一部の問題に分けます.
したがって,座標(x,y)上の最大スコアが注釈の対象となる.
問題では2つの行動をとることができます.現在座標(x,y)のシールを取り外します.
隣接する のシールは取り外すことができず、上下に取り外します.したがってmod演算を用いる. は取り外さず、次のコーナーに進みます.
1.トラブルシューティング
問題に明確な条件を以下のように整理する.
1-1. 部分的な問題に分ける
大きな問題は「何枚かのシールを引き裂いても最大点数がもらえる」ということです.これを「現在の座標(x,y)に格納されている最大スコア」という一部の問題に分けます.
したがって,座標(x,y)上の最大スコアが注釈の対象となる.
1-2. 開けますか?もういいよ。
問題では2つの行動をとることができます.
隣接する
2.ソースコード
//스티커
import java.io.*;
import java.util.*;
public class Main {
static int [][]cache, array;
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());
for(int i =0 ; i < tc ; i++) {
int n = Integer.parseInt(br.readLine());
StringTokenizer st =null;
array = new int[2][n];
for(int j =0 ; j < 2 ; j++) {
st= new StringTokenizer(br.readLine());
for(int k =0 ; k < n ; k++) {
array[j][k] = Integer.parseInt(st.nextToken());
}
}
cache = new int[2][n];
for(int [] c : cache)
Arrays.fill(c, -1);
System.out.println(Math.max(dp(0,0), dp(1,0)));
}
}
private static int dp(int x, int y) {
if(y == array[x].length)
return 0;
if(cache[x][y] != -1)
return cache[x][y];
int ret =0;
//현재 스티커를 떄는 경우
ret = dp((x+1)%2, y+1) + array[x][y];
//안 때는 경우
ret = Math.max(dp(x,y+1),ret);
return cache[x][y] = ret;
}
}
Reference
この問題について(シール枚), 我々は、より多くの情報をここで見つけました https://velog.io/@jms8732/9465.-스티커テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol