TOI 2021.11 潛力組(二) 校隊(School Team) Java 解題心得( 題目 )

解題概念:DP

更新:這題可以greedy,詳見下方!

解題方法:我們令dp[i][j]=在前i+j個班選i個男、j個女的最小時間sum,其實我們就可以得到最小值dp[n][m]

轉移式:dp[i][j]=min(dp[i-1][j]+boy[i+j], dp[i][j-1]+girl[i+j])

 (註:這裡設班級從1開始,boy[i]代表第i班男生時間,girl[i]代表第i班女生時間)

Java參考程式碼(有更好意見可留言於下方,謝謝!)

import java.io.*;

public class zjg774 {

    public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

    public static int r,ret;

    public static int[][] dp=new int[2005][2005];

    public static int[][] in=new int[2][4005];//輸入

    public static void main(String[] args) throws Exception {

        int n=readint();

        int m=readint();

        for(int i=1;i<=n+m;i++) {

            in[0][i]=readint();//男

            in[1][i]=readint();//女

        }

        for(int i=1;i<=n;i++) {

            dp[i][0]=dp[i-1][0]+in[0][i];
        }


        for(int j=1;j<=m;j++) {

            dp[0][j]=dp[0][j-1]+in[1][j];//初始邊界

        }

        for(int i=1;i<=n;i++) {

            for(int j=1;j<=m;j++) {

                dp[i][j]=Math.min(dp[i-1][j]+in[0][i+j], dp[i][j-1]+in[1][i+j]);

            }

        }

        System.out.println(dp[n][m]);

    }



    public static int readint() throws Exception {

              //輸入

        ret=0;

        r=br.read();

        while(r>47&&r<58) {

            ret*=10;

            ret+=(r&15);

            r=br.read();

        }

        return ret;

    }

}

感謝fire5386 (fffelix)提供greedy解法:

用greedy 計算每個班級的差(男-女)然後排序 最大的n個取男生 剩下取女生

這樣似乎greedy的解法比較簡潔,而且複雜度也還不錯(甚至可以說比低批好),下方提供比較一下:

DP O(mn)

Greedy O(tlogt) (假設總人數t=m+n)

 

文章標籤
全站熱搜
創作者介紹
創作者 En Chi Tsung 的頭像
En Chi Tsung

阿祁的部落格

En Chi Tsung 發表在 痞客邦 留言(0) 人氣(107)