FZU:Problem 1864 Christmas Machine

http://acm.fzu.edu.cn/problem.php?pid=1864
Problem 1864 Christmas Machine

Accept: 22    Submit: 71
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

As Christmas come,members in Fzu ACM Lab all want to have a rest.But they must face a lots of pending jobs which haven’t been completed by their judging machines.They want to finish them as soon as possible.

As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling problems differ widely in the nature of the constraints that must be satisfied and the type of schedule desired. Here we consider a 2-machine scheduling problem.

There are two judging machines A and B in the Lab. Machine A has n kinds of working modes, which is called mode_0, mode_1, …, mode_n-1, likewise machine B has m kinds of working modes, mode_0, mode_1, … , mode_m-1. At the beginning they are both work at mode_0.

For k jobs given, each of them can be processed in either one of the two machines in particular mode. For example, job 0 can either be processed in machine A at mode_3 or in machine B at mode_4, job 1 can either be processed in machine A at mode_2 or in machine B at mode_4, and so on. Thus, for job i, the constraint can be represent as a triple (i, x, y), which means it can be processed either in machine A at mode_x, or in machine B at mode_y.

Note that the jobs must be processed in order and the job with lower index comes first.

Obviously, to accomplish all the jobs, we need to change the machine's working mode from time to time, but unfortunately, the machine's working mode can only be changed by restarting it manually. By assigning each job to a suitable machine,they want to minimize the times of restarting machines.

 Input

The first line contains an integer T representing the number of configuration. Then following T configurations.

The first line of one configuration contains three positive integers: n, m (0 < n, m < 50) and k (k < 500). The following k lines give the constrains of the k jobs, the ith line contains two integers x,y,thus (i,x,y) reperesents a triple as described above.

There may be several blank lines between each input cases.

 Output

The output should be one integer per line, which means the minimal times of restarting machine.

 Sample Input

12 2 30 11 01 1

 Sample Output

1


这道题是machine schedule题目改动而来的,要求任务必须按照给定的顺序执行,
所以只能选择dp了。
定义table[i][j][k] 表示到第i道工序,机器1在j个状态,机器2在第k个状态需
要restart的最小次数,t1[i]表示机器1在工序i所需要的状态,t2[i]表示机器2
在工序i所需要的状态,显然只有table[i][j][k](j == t1[i] && 0 <= k < m) 
||(0 <= j < n && k == t2[i])才是有效,此题我逆推话大脑会混乱的,所以选择
正推,考虑状态table[i][j][k],这个状态可以转移到
table[i+1][t1[i+1]][x](0<=x<m)和table[i+1][y][t2[i+1]]( 0<=y<n),
但实际上最优转移只有
table[i+1][t1[i+1]][k]和table[i+1][j][t2[i+1]]俩种,考虑机器1,因为
当前并没有把k改变成x的必要,而其子状态如果有需要调节成x的需要,则可以到那时再
调整,而耗费都是1,并没有增加,这样时间复杂度也就降到了O(k*n*m)。

代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;



const int INFI((INT_MAX-1) >> 1);

int table[2][52][52];

int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		int n, m, k;
		scanf("%d%d%d", &n, &m, &k);
		int cur(0), last(1);
		for(int j = 0; j < n; ++j)
				for(int k = 0; k < m; ++k)
					table[last][j][k] = INFI;
		table[last][0][0] = 0;
		int t1, t2;
		for(int i = 0; i < k; ++i)
		{
			for(int j = 0; j < n; ++j)
				for(int k = 0; k < m; ++k)
					table[cur][j][k] = INFI;
			scanf("%d%d", &t1, &t2);
			for(int j = 0; j < n; ++j)
			{
				int count1 = j == t1? 0: 1;
				for(int k = 0; k < m; ++k)
				{
					table[cur][t1][k] = min(table[cur][t1][k], table[last][j][k]+count1);
					int count2 = k == t2? 0: 1;
					table[cur][j][t2] = min(table[cur][j][t2], table[last][j][k]+count2);
				}
			}
			swap(cur, last);
		}
		int ans = INFI;
		for(int i = 0; i < n; ++i)
			ans = min(ans, table[last][i][t2]);
		for(int i = 0; i < m; ++i)
			ans = min(ans, table[last][t1][i]);
		printf("%d\n", ans);
	}
	return 0;
}



你可能感兴趣的:(FZU:Problem 1864 Christmas Machine)