1. 程式人生 > >HDU1074 Doing Homework

HDU1074 Doing Homework

temp 題目 需要 value per close new () logs

HDU1074 Doing Homework

題目描述

題目共有 T 組測試, 每組測試給定 n 個作業, 每個作業有 完成需要的時間截止日期, 所有作業都需要完成, 每超過截止日期一天就會扣一分, 問最少扣分 以及 完成次序.

解題思路

第一次做 狀態壓縮DP 的題, 題目的解的值和不同科目的次序相關, 如果需要窮舉次序的話共有 N! (n屬於[1, 15]) 種方案

可以 使用 n 位的二進制來表示 n 種方案是否完成, 如果有 A, B, C 三個作業, 可以使用 001 表示只有 A 完成. 對於 ABC 之後的 D 來講, ABC完成 次序與到達 D 的時間花費無關, ABC 的不同排列會使到達 D 的扣的分數不同, 而在 D 時只需要選擇分數被扣最小的方案即可.

對於每個狀態, 如 001110, 可以從 三個狀態 001100, 001010, 000110 轉移得到, 因此需要 枚舉每一位 , 看這一位是否為 該狀態的前置狀態 , 是的話, 則通過計算 前面狀態的最小花費被枚舉事件的所扣分數 來更新該狀態被扣分數的最小值.

由於當前枚舉的為現在做的作業, 即在前面作業完成後完成的, 因此需要從大數開始枚舉, 前面的小數在 i 的循環時已經得到了相應的狀態.

代碼

package 基礎DP1;

import java.util.Scanner;
import java.util.Stack;
class Homework {
    public String name;
    public
int deadline; public int cost; public Homework(String name, int deadline, int cost) { super(); this.name = name; this.deadline = deadline; this.cost = cost; } } class Node { public int nowtime; public int score; public int num; public
int pre; } public class HDU1074 { public static void main(String[] args) { Scanner in = new Scanner(System.in); int nCase = in.nextInt(); while(0 != nCase--) { int nSubject = in.nextInt(); Homework[] h = new Homework[nSubject]; for(int i = 0; i < nSubject; i++) { String name = in.next(); int deadline = in.nextInt(); int cost = in.nextInt(); h[i] = new Homework(name, deadline, cost); } int nSta = (1 << nSubject) - 1; Node[] dp = new Node[nSta + 1]; for(int i = 0; i <= nSta; i++) dp[i] = new Node(); for(int i = 1; i <= nSta; i++) { dp[i].score = Integer.MAX_VALUE; for(int j = nSubject - 1; j >= 0; j--) { int temp = 1 << j; if((temp & i) != temp) continue; int k = i - temp; int x = dp[k].nowtime + h[j].cost - h[j].deadline; if(x < 0) x = 0; if(dp[k].score + x < dp[i].score) { dp[i].score = dp[k].score + x; dp[i].nowtime = dp[k].nowtime + h[j].cost; dp[i].num = j; dp[i].pre = k; } } } System.out.println(dp[nSta].score); Stack<Integer> st = new Stack<Integer>(); while(nSta != 0) { st.push(dp[nSta].num); nSta = dp[nSta].pre; } while(!st.isEmpty()) { System.out.println(h[st.peek()].name); st.pop(); } } in.close(); } }

參考鏈接

HDU 1074:Doing HomeWork(狀態壓縮DP)

[HDU 1074 (狀態壓縮DP)](http://www.cnblogs.com/neopenx/p/4048722.html)

HDU1074 Doing Homework