标签:
Description
Input
Output
Sample Input
2 3 Computer 3 3 English 20 1 Math 3 2 3 Computer 3 3 English 6 3 Math 6 3
Sample Output
2 Computer Math English 3 Computer English Math
Hint
In the second test case, both Computer->English->Math and Computer->Math->English leads to reduce 3 points, but the word "English" appears earlier than the word "Math", so we choose the first order. That is so-called alphabet order.
给出了n门作业,每科做也的提交时间和需要时间,每超过一天罚1分,问最少罚几分,要求最小字典序
状态表示,在n科中做了哪几科,二进制数中第i个为1表示做了第i科,dp[i]表示状态为i时的最少罚时,和已经用了的分数
状态转移方程从科目为j的转移到科目为j+1的
为保证字典序最小,所以要让dp[i]尽量有更小的i来得到。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; struct node { char s[120] ; int d , c ; } p[20]; int state[20][7000] , num[20] , c[20] , cnt ; int dp1[20][7000] , dp2[20][7000] , step[20][7000] ; //dp[i][j][]写i科作业在状态j时,0代表超出的时间,1代表需要的时间。 int find1(int x,int i) { //printf("x == %d i == %d\n", x, i) ; int low = 0 , mid , high = num[i]-1 ; while( low <= high ) { mid = ( low + high ) ; //printf("mid--%d\n", mid) ; if( state[i][mid] == x ) return mid ; else if( state[i][mid] > x ) high = mid - 1 ; else low = mid + 1 ; } } int main() { int t , n , i , j , k , l , x , y , temp ; scanf("%d", &t) ; while( t-- ) { memset(num,0,sizeof(num)) ; memset(dp1,-1,sizeof(dp1)) ; memset(step,-1,sizeof(step)) ; memset(dp2,-1,sizeof(dp2)); scanf("%d", &n) ; for(i = 1 ; i <= n ; i++) scanf("%s %d %d", p[i].s, &p[i].d, &p[i].c) ; x = 1<<n ; for(i = 0 ; i < x ; i++) { for(j = 0 , temp = 0 ; j < n ; j++) if( (1<<j) & i ) temp++ ; state[temp][ num[temp]++ ]= i ; } /* for(i = 0 ; i <= n ; i++) { for(j = 0 ; j < num[i] ; j++) printf("%d ", state[i][j]) ; printf("\n") ; }*/ dp1[0][0] = dp2[0][0] = 0 ; for(i = 0 ; i < n ; i++) { for(j = 0 ; j < num[i] ; j++) { for(k = 1 ; k <= n ; k++) { if( 1<<(k-1) & state[i][j] ) continue ; l = find1(state[i][j]+(1<<(k-1)),i+1) ; //printf("l == %d\n", l ) ; if( dp1[i+1][l] == -1 || ( dp1[i+1][l] > dp1[i][j] + max(dp2[i][j]+p[k].c-p[k].d,0) ) ) { dp1[i+1][l] = dp1[i][j] + max(dp2[i][j]+p[k].c-p[k].d,0) ; dp2[i+1][l] = dp2[i][j]+p[k].c ; step[i+1][l] = j ; } } } } /*for(i = 0 ; i <= n ; i++) { for(j = 0 ; j < num[i] ; j++) printf("%d ", dp[i][j][0]) ; printf("\n") ; }*/ cnt = 0 ; for(i = n , j = 0 ; i > 0 ; i--) { x = state[i][j] ; y = state[i-1][ step[i][j] ] ; //printf("x = %d y = %d\n", x, y) ; for(k = 1 ; k <= n ; k++) { if( x % 2 != y % 2 ) break ; x /= 2 ; y /= 2 ; } c[cnt++] = k ; j = step[i][j] ; } int min1 = dp1[n][0] ; printf("%d\n", min1) ; for(i = cnt - 1 ; i >= 0 ; i--) printf("%s\n", p[c[i]].s ) ; } return 0 ; }
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42586359