【Codeforces 467C】George and Job
阿新 • • 發佈:2019-02-17
tokenizer tin code int() adl def size 當前位置 ret
【鏈接】 我是鏈接,點我呀:)
【題意】
讓你從1..n這n個數字中
選出來k個不相交的長度為m的區間
然後這個k個區間的和最大
求出這k個區間的和的最大值
【題解】
設dp[i][j]表示前i個數字已經選出了j個區間的最大值
看看是以當前位置為結尾選擇一個區間,還是這個位置不包括在任何一個區間裏.
分這兩種情況轉移就好
【代碼】
import java.io.*; import java.util.*; public class Main { static InputReader in; static PrintWriter out; public static void main(String[] args) throws IOException{ //InputStream ins = new FileInputStream("E:\\rush.txt"); InputStream ins = System.in; in = new InputReader(ins); out = new PrintWriter(System.out); //code start from here new Task().solve(in, out); out.close(); } static int N = 5000; static class Task{ int n,m,k; int a[]; long sum[]; long dp[][]; long get_sum(int l,int r) { return sum[r]-sum[l-1]; } public void solve(InputReader in,PrintWriter out) { n = in.nextInt();m = in.nextInt();k = in.nextInt(); a = new int[N+10]; sum = new long[N+10]; dp = new long[N+10][N+10]; for (int i = 1;i <= n;i++) { a[i] = in.nextInt(); } for (int i = 1;i <= n;i++) sum[i]=sum[i-1]+a[i]; long ans = 0; dp[0][0] = 0; for (int i = 1;i <= n;i++) for (int j = 0;j <= Math.min(k, i);j++) { if (j==0) { dp[i][j] = Math.max(dp[i][j], dp[i-1][j]); }else { if (i-m>=0) { dp[i][j] = Math.max(dp[i][j], dp[i-m][j-1]+get_sum(i-m+1,i)); dp[i][j] = Math.max(dp[i][j], dp[i-1][j]); } } ans = Math.max(ans, dp[i][j]); } out.println(ans); } } static class InputReader{ public BufferedReader br; public StringTokenizer tokenizer; public InputReader(InputStream ins) { br = new BufferedReader(new InputStreamReader(ins)); tokenizer = null; } public String next(){ while (tokenizer==null || !tokenizer.hasMoreTokens()) { try { tokenizer = new StringTokenizer(br.readLine()); }catch(IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } } }
【Codeforces 467C】George and Job