zoukankan      html  css  js  c++  java
  • POJ 1180 Batch Scheduling

    BTW:

    刚在图书馆借了本算法艺术与信息学竞赛. 我多次有买这本书的冲动, 但每次在试看之后就放弃了, 倒不是因为书太难, 而是写的实在是太差. 大家对这本书的评价很高, 我觉得多是因为书的内容, 而作者表达内容与思想的方式真是令我恼火. programmer 写博客, 尤其是技术博客, 往往不去考虑读者的起点, 结果博客都成了自己给自己看的地方. 报纸杂志都属于通俗易懂的材料, 不需要假定读者的水平如何. 而写书, 则必须要好好考虑读者的水平. 单说算法书, 全世界的算法书加起来也得有个上千本, 但是能称为经典的屈指可数, 而经典书的作者在写书时必然仔细考虑了所面向的读者, 读者的水平和读者所处的上下文. 国人常说, 只可意会不可言传, 我觉得这是表达能力不足的借口. 书的目的便是要省去或起码减少 "悟" 所需要的时间. 我读这道题时最大的感受是作者东一句话西一句话, 以自己的思路和上下文在写书. 需要我花大量的时间去悟. 花了半小时, 知道一段话的意思, 恍然大悟原来如此 --- I hate that. 黑书内容虽好, 写的太差

    思路:

    1. dp[i] 表示从第 i 个任务开始, 到最后一个任务结束所需的最小总代价

    2. dp[i] = min{ dp[j] +w(i,j)}, j > i} w(i, j) = (S + sumT(i) - sumT(j)) * sumF(i)

    状态转移方程表示求解 dp[i] 的最优解时, 枚举在 j 处切一刀的所有情况, 即 {i,j之间的任务}U{dp[j]的最优解}, 选取最优的 j

    另外, w(i, j) = (S + sumT(i) - sumT(j)) * sumF(i) 这个式子的右端乘上的是 sumF(i) 而不是 sumF(i)-sumF(j), 这是因为预先把 dp[j] 的代价计算了, 这样, "在状态转移方程时就可以每次看作从时间 0 开始工作了", 就不需考虑 dp[i] 是什么时候完成的任务了

    比如在给定的测试用例中

    5个任务的划分为5个组, 每组一个任务

    组1 : 完成时间 0+1+1=2,    代价 3, 耗费 2 * 3 = 6  

    组2 : 完成时间 2+1+3=6,    代价 2, 耗费 6 * 3 = 18

    组3 : 完成时间 6+1+4=11,  代价 3, 总耗费 11 * 3 = 33

    组4 : 完成时间 11+1+2=14, 代价 3, 总耗费 14 * 3 = 42

    组5 : 完成时间 14+1+1=16, 代价 4, 总耗费 16 * 4 = 64

    假定 {1,2} {3,4,5} 分成两组, 前两组的完成时间为 6, 在3,4,5组减去(S + sumT(i) - sumT(j)) * sumF(i), 相当于

    6+1+4 ---> 0+1+4

    11+1+2--->5+1+2

    14+1+1--->11+1+1

    从 3 的视角来看, 组3似乎是从时间 0 开始计算的 

    3. 从 (2) 知, 是倒推的过程

    总结:

    1. 顺序切割的动态规划解法

    2. 计算 w[i,j] 的时候, 需要非常小心 

    代码:

    没看懂优化原理, o(n*n) 的 MLE + TLE 代码

    #include <iostream>
    using namespace std;
    
    const int MAXN = 10010;
    int N, S;
    int t[MAXN], f[MAXN];
    int st[MAXN], sf[MAXN];
    int w[MAXN][MAXN];
    int dp[MAXN];
    
    void pre_process() {
    	memset(st, 0, sizeof(st));
    	memset(sf, 0, sizeof(sf));
    	for(int i = N; i > 0 ; i --) {
    		st[i] = t[i] + st[i+1];
    		sf[i] = f[i] + sf[i+1];
    	}
    
    	memset(w, 0, sizeof(w));
    	for(int i = 1; i <= N; i ++) {
    		for(int j = i+1; j <= N; j ++) {
    			w[i][j] = (S + st[i]-st[j])*sf[i]; 
    		}
    	}
    
    	memset(dp, 0, sizeof(dp));
    	for(int i = N; i > 0; i --) {
    		dp[i] = (S+st[i])*sf[i];
    	}
    
    }
    int mainFunc() {
    	
    	for(int i = N-1; i > 0; i --) {
    		for(int j = i+1; j <= N; j ++) {
    			dp[i] = min(dp[i], dp[j]+w[i][j]);
    		}
    	}
    	return dp[1];
    }
    int main() {
    	//freopen("E:\Copy\ACM\poj\1180\in.txt", "r", stdin);
    	while(cin >> N >> S) {
    		for(int i = 1; i <= N; i ++) {
    			scanf("%d%d", &t[i], &f[i]);
    		}
    		pre_process();
    		// mainFunc
    		cout << mainFunc() << endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SecureCRT_FX8.0完整版
    bridge
    Quartz 框架 教程(中文版)2.2.x
    Quartz教程五:SimpleTrigger
    Quartz教程四:Trigger
    Quartz教程三:Job与JobDetail介绍
    Quartz教程二:API,Job和Trigger
    Quartz教程一:使用quartz
    Quartz教程:快速入门
    Kubernetes 1.5.3 部署
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3451171.html
Copyright © 2011-2022 走看看