TOJ 2898
来源:互联网 发布:北明软件 中标 编辑:程序博客网 时间:2024/05/16 10:22
题目标题:
Employment Planning
题目连接:
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=2898
题目类型:
动态规划
数据结构:
// month, workerint dp[15][MAXPLE];
思路分析:
给定每个月最低工作人数,
决定雇佣或者裁员或者保持原样
使得总支出最小
典型的动态规划问题
关键是以每个月为一个决策节点
对当月的不同人数对比上个月的各种情况人数施以计算,
当月每个人数都保留最优有效解
则最后一个月的最少支出为答案..
比如 第一个月 对最少人数至最多人数计算 保留各个值
第二个月 最低人数9个人的情况 对 一月份各个人数情况计算 取最小值
再10个人的情况 对上一个月再执行重复的步骤 保留当月最小值
证明:
1. 所有雇员行为都是越迟越好, 至少不会得到更差的解
此思路建立在每个月都是对前几个月独立的情况上
每个月相当于都是新的决策点 不受过去情况的影响.
源代码:
#include <iostream>#include <stdio.h>using namespace std;#define MAXPLE 205// month, workerint dp[15][MAXPLE];int main(){int i, j, k, maxples;int months;int hiring, salary, firing;int arr[13];while( scanf( "%d", &months ), months ){maxples = -1;memset( arr, 0, sizeof( arr ) );memset( dp, 0, sizeof( dp ) );scanf( "%d%d%d", &hiring, &salary, &firing );for( i = 1; i <= months; i ++ ){scanf( "%d", arr + i );if( arr[i] > maxples ){maxples = arr[i];}}for( i = arr[1]; i <= maxples; i ++ ){dp[1][i] = hiring * i + salary * i;}for( i = 2; i <= months; i ++ ){for( j = arr[i]; j <= maxples; j ++ ){int tmp = 0, min = INT_MAX;for( k = arr[i - 1]; k <= maxples; k ++ ){if( dp[i - 1][k] ){tmp = dp[i - 1][k] + j * salary + ( j > k ? ( j - k ) * hiring : ( k - j ) * firing );if( tmp < min ){min = tmp;}}}dp[i][j] = min;}}int m = INT_MAX;for( i = arr[months]; i <= maxples; i ++ ){if( dp[months][i] < m ){m = dp[months][i];}}printf( "%d\n", m );}return 0;}
优化:
只需对所有月份中最大人数的那个当上界即可
没有必要对所有可能的人数求解
在 HDOJ 15MS 在 TOJ 500MS 左右
0 0
- TOJ 2898
- TOJ 2976
- toj 3140
- toj 1153
- TOJ 1772
- TOJ 3250
- TOJ 3051
- TOJ 4303
- TOJ 1005
- TOJ 1545
- TOJ 2378
- TOJ 1537
- TOJ 1252
- TOJ 1408
- TOJ 1509
- TOJ 2882
- TOJ 1052
- TOJ-ACM
- Cannot open include file: 'stdafx.h': No such file or directory.
- MtGox破产,对比特币是致命一击
- 有上下界网络流问题
- 类似搜狐新闻的栏目定制
- MP算法和OMP算法及其思想
- TOJ 2898
- 翻转字符串
- 做PPT的思路
- SQL中CONVERT转化函数的用法
- Bundle类
- mac 下升级svn到1.70
- JAVA线程同步(一)
- 数据库引擎
- IOS 如何让xcode自动检查内存泄露