[BaekJoon]1495ギタリスト


1.  質問リンク


https://www.acmicpc.net/problem/1495

2.  質問する



サマリ

  • N曲を演奏し、各曲が始まる前に、最初の曲をV[i]のように音量調整することができます.
  • は、現在の音量がPであり、i番目の曲を演奏する前に、i番目の曲がP+V[i]またはP-V[i]の音量で演奏される.
  • の場合、ボリュームはゼロ以上、M以下でなければなりません.
  • が最も最初に演奏する曲の数がN、N曲の曲リストV、開始曲S、最大曲Mである場合、最後の曲の中で最も値が大きい.
  • 入力
  • :第1動作N、S、M、第2動作各曲の開始前に与えられる音量差V.
  • 出力:1行目に可能な最後の曲の最大音量を出力します.
  • 3.  ソースコード

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.StringTokenizer;
    
    public class Main {
    	int[][] dp;
    	static int start_vol, max_vol, song_num;
    	static int[] dif_volume;
    	
    	public int findVolume(int sum, int index) {
    		if(0 > sum || sum > max_vol) {
    			return -1;
    		}
    		if(index == song_num) {
    			return sum;
    		}
    		if(dp[sum][index] != -10) {
    			return dp[sum][index];
    		}
    		return dp[sum][index] = Math.max(dp[sum][index], Math.max(findVolume(sum + dif_volume[index], index + 1), findVolume(sum - dif_volume[index], index + 1)));
    	}
    	
    	public int getMaxVolume() {
    		dp = new int[max_vol + 1][dif_volume.length];
    		for(int i = 0; i < dp.length; i++) {
    			for(int j = 0; j < dp[i].length; j++) {
    				dp[i][j] = -10;
    			}
    		}
    		return findVolume(start_vol, 0);
    	}
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    		
    		String input = br.readLine();
    		StringTokenizer st = new StringTokenizer(input);
    		song_num = Integer.parseInt(st.nextToken());
    		start_vol = Integer.parseInt(st.nextToken());
    		max_vol = Integer.parseInt(st.nextToken());
    		dif_volume = new int[song_num];
    		input = br.readLine();
    		br.close();
    		st = new StringTokenizer(input);
    		for(int i = 0; i < dif_volume.length; i++) {
    			dif_volume[i] = Integer.parseInt(st.nextToken());
    		}
    		Main m = new Main();
    		bw.write(m.getMaxVolume() + "\n");
    		bw.flush();
    		bw.close();
    	}
    }

    4.  に近づく

  • この問題はDPによって解決することができる.
  • dpという名前の2 D配列を作成し、まだアクセスされていない場所を-10として表すために、dp配列を-10に初期化します.
  • の開始ボリュームから、次のボリューム(現在のボリューム-次のボリューム)と(現在のボリューム+次のボリューム)を使用できますが、最後の曲の音量は最大でなければなりません.したがって、より大きな値を取得し、現在のボリュームのより大きな値を現在のボリュームとして取得できます.
  • の場合、音量が0より小さくないかMより大きくないために問題があって最後の曲を演奏できない場合、出力−1が要求されるため、この場合、この値は−1となる.
  • indexがすべての数を返した場合、最後の曲の音量は和になり、sumに戻ります.
  • 回目のプロシージャ(現在のボリューム-次のボリューム)と(現在のボリューム+次のボリューム)では、再帰ループを使用して最後にループし、最後の曲で可能な最大ボリュームを取得できます.