Problem B: Situp Benches
![Joe Six-Pack](http://uva.onlinejudge.org/external/115/p11578.png)
The gym at the University of Alberta has two identical sit up benches that are side by side. Each of these benches can be inclined in 10 degree increments between 10 degrees and 50 degrees inclusive depending on the level of difficulty the user desires. At the end of each day the gym staff adjust the incline of each machine to be 10 degrees. This means at the start of each day both machines have a 10 degree incline.
Every time someone uses a bench it incurs some wear and tear that amounts to 15 cents in maintenance costs. Additionally, every time a bench has its incline changed it incurs wear and tear that amounts to the number of degrees the bench was adjusted, in cents. For example, if someone moves the bench from a 40 degree incline to a 20 degree incline then 20 cents of maintenance must be done.
The gym staff have recently required students to sign up for the situp benches the day before. When a student signs up they give the time at which they would like to use the machine and the incline they will use it at. No more than two students can sign up to use a bench at the same time.
Prior to opening the gym for the day, the gym staff would like to have a list assigning students to each of the situp benches and they would like the assignment to minimize the total maintenance cost for the day. They have asked you to write a program to make this list.
Input begins with the number of test cases on its own line. Each test case begins with the number n (1 ≤ n≤ 10000), the number of students who have signed up to use the benches on the following day. Following aren lines, each consisting of two numbers: time_slot and incline. time_slot is a number that specifies when a student will arrive at the machine, while incline specifies the angle to which they will adjust the situp bench. Two students in the same time_slot arrive at the benches at the same time, and lower time_slots occur before higher time_slots. time_slots are numbered between 0 and 20000, and incline is one of 10, 20, 30, 40 or 50 depending on the student's preference.
For each test case, output a line containing the total maintenance cost (in cents) for the day followed by nlines (one for each student, in the order given on input) containing either a 1 or a 2 depending on which bench you have assigned them to. Any assignment that minimizes the total maintenance cost for the day is acceptable.
Sample Input
1 3 2 40 2 50 1 40
Sample Output
185 1 2 1
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int maxn = 10010; int dp[maxn][55][55][3]; int vis[maxn][55][55][3]; int sit[maxn] , n ,v; struct student{ int time_slot; int degree; int id; student(int t = 0, int d = 0 ,int i = 0){ time_slot = t , degree = d , id = i; } }stu[maxn]; bool cmp(student s1 , student s2){ if(s1.time_slot == s2.time_slot){ return s1.degree < s2.degree; } return s1.time_slot < s2.time_slot; } void readcase(){ scanf("%d" , &n); int t , d; for(int i = 0;i < n;i++){ scanf("%d%d" , &t , &d); stu[i] = student(t , d, i); } sort(stu , stu+n , cmp); } int DP(int k , int d1 , int d2 , int pre){ if(k >= n) return d1+d2-20; if(vis[k][d1][d2][pre] == v) return dp[k][d1][d2][pre]; int ans = 1000000000; if(pre == 0){ ans = DP(k+1 , stu[k].degree , d2 , 1)+abs(d1-stu[k].degree); }else if(stu[k].time_slot != stu[k-1].time_slot){ int t2 = DP(k+1 , d1 , stu[k].degree , 2)+abs(d2-stu[k].degree); ans = DP(k+1 , stu[k].degree , d2 , 1)+abs(d1-stu[k].degree); if(ans > t2){ ans = t2; } }else{ if(pre == 1){ ans = DP(k+1 , d1 , stu[k].degree , 2)+abs(d2-stu[k].degree); }else{ ans = DP(k+1 , stu[k].degree , d2 , 1)+abs(d1-stu[k].degree); } } vis[k][d1][d2][pre] = v; return dp[k][d1][d2][pre] = ans; } void find_sit(){ int pre = 0 , d[2] = {10 , 10}; for(int i = 0;i < n;i++){ if(pre == 0){ sit[stu[i].id] = 1; pre = 1; d[0] = stu[i].degree; }else{ if(stu[i].time_slot != stu[i-1].time_slot){ if(DP(i,stu[i].degree,d[1],1)+abs(d[0]-stu[i].degree) <= DP(i,d[0],stu[i].degree,2)+abs(d[1]-stu[i].degree)){ sit[stu[i].id] = 1; d[0] = stu[i].degree; pre = 1; }else{ sit[stu[i].id] = 2; d[1] = stu[i].degree; pre = 2; } }else{ pre = pre%2+1; sit[stu[i].id] = pre; d[pre-1] = stu[i].degree; } } } } void computing(){ printf("%d\n" , DP(0 , 10 , 10 , 0)+15*n); find_sit(); for(int i = 0;i < n;i++){ printf("%d\n" , sit[i]); } } int main(){ int t; scanf("%d" , &t); v = 1; while(t--){ memset(sit , 0, sizeof sit); readcase(); computing(); v++; } return 0; }