Doing Homework Time limit:2000/1000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 10297 Accepted Submission (s): 4963
Problem Description Ignatius have just come back school from the 30th ACM/ICPC. Now he had a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher would reduce his score of the final Test, 1 day for 1 poi Nt. And as you know, doing homework always takes a long time. So Ignatius wants-to-help him to arrange the order of doing homework to minimize the reduced score.
Input the input contains several test cases. The first line of the input was a single integer T which is the number of test cases. T test Cases follow.
Each test case is start with a positive integer N (1<=n<=15) which indicate the number of homework. Then N lines follow. Each line contains a string S (the subject's name, each string would at the most have characters) and a integers D (the dead Line of the subject), C (what many days would it take Ignatius to finish this subject ' s homework).
Note:all the subject names is given in the alphabet increasing order. So, may process the problem much easier.
Output for each test case, you should output the smallest total reduced score, then give out the order of the subjects, on e subject in a line. If there is more than one orders, you should output the alphabet smallest one.
Sample Input
2 3 Computer 3 3 中文版 1 Math 3 2 3 computer 3 3 中文版 6 3 Math 6 3
Sample Output
2 computer Math 中文版 3 computer Chinese math Hint in the second Test case both Computer->english->math and Compu Ter->math->english leads to reduce 3 points, but the word "中文版" appears earlier than the word "Math", so we Choo Se the first order. That is so-called alphabet order.
123
"State Compression"
Just learn about state compression;
The most common form of pressure is & | << >> operations; for n < generally less than 20 (2^20 is no longer a general 15,10); We put a state in 0/1, so there's a 2^n state.
Then enumerate the state, and in the current state, determine whether a situation is in line with the next step;
Four kinds of operations: (moved here)
1. The ' & ' symbol, X&Y, will operate the two decimal digits in binary and return its decimal value. For example 3 (one) &2 (10) =2 (10).
2. ' | ' Symbol, X|y, will make two decimal digits in binary or operation, and then return the value under its decimal. For example, 3 (11) (10) =3 (11).
3. The ' ^ ' symbol, X^y, performs an XOR operation on the two decimal digits in binary, then returns its decimal value. For example, 3 (11) ^2 (10) =1 (01).
4. ' << ' symbol, left shift, X<<2, move X to the left of each bit in the binary two bits, the rightmost 0 padding, x<<2 equivalent to x multiplied by 4. Accordingly, ' >> ' is the right shift operation, x>>1 equivalent to X/2, minus the x binary under the most one bit.
and application;
1. Determine if the second digit x binary is equal to 1.
Method: if (((1 << (i-1) & X) > 0)
Shift 1 to the left I-1 bit, which is equivalent to creating a binary number that is only the first I bit is 1 and the other bits are 0. Then with X do with the operation, if the result is >0, the X-I position is 1, and vice versa is 0.
2. Change the first digit x binary to 1.
Method: x = x | (1<< (i-1))
The proof method is similar to 1 and is not repeated here.
3. Remove the first 1 on the right with a binary number.
Method:x=x& (X-1)
applications use the most;
"HDU 1074"
According to the dictionary order, then the path is recorded, where the stack pre records the precursor;
Code
#include <bits/stdc++.h> #include <iostream> #include <stdio.h> #include <algorithm> # Include <cmath> #include <math.h> #include <cstring> #include <string> #include <queue> # Include <stack> #include <stdlib.h> #include <list> #include <map> #include <set> #include <bitset> #include <vector> #define MEM (A, B) memset (A,b,sizeof (a)) #define FINDX (x) lower_bound (B+1,b+1+bn, x)-B #define FIN freopen ("Input.txt", "R", stdin) #define FOUT freopen ("Output.txt", "w", stdout) #define S1 (n) SC ANF ("%d", &n) #define SL1 (n) scanf ("%i64d", &n) #define S2 (n,m) scanf ("%d%d", &n,&m) #define SL2 (n,m) SCA NF ("%i64d%i64d", &n,&m) #define PR (n) printf ("%d\n", N) #define Lson RT << 1, L, MID #define Rson RT <& Lt
1|1, Mid + 1, r #define MEM (A, B) memset (A,b,sizeof (a)) typedef long Long LL;
const int inf=0x3f3f3f3f;
const LL MOD=1E9+7;
const int maxn=1e5+5; const INT N=16; ll Qpow (ll x,ll N) {ll res=1;for (; n;n>>=1) {if (n&1) res= (res*x); x= (x*x);}
return res;}
using namespace Std;
struct node{string name;
int cost,dead;
}A[100]; struct nnode{int time,pre,score,now;}
dp[1<<n];
int main () {int T;
cin>>t;
int n;
while (t--) {scanf ("%d", &n);
for (int i=0;i<n;i++) {cin>>a[i].name>>a[i].dead>>a[i].cost;
} mem (dp,0);
int bit= 1<<n;
for (int i=1;i<bit;i++)//enumeration state {Dp[i].score=inf; for (int j= n-1;j>=0;j--)//Enumerate all Job test instructions, finish one and put it in the back, then look at the state, j before the can reach J {int te= 1<&
Lt;j;
if (Te & i) {int past = I-te;
int val = dp[past].time + a[j].cost-a[j].dead;
if (val<0) val=0;
if (val + dp[past].score < Dp[i].score) {dp[i].score= val + dp[past].score;
Dp[i].now=j;
Dp[i].pre= past;
Dp[i].time= Dp[past].time + a[j].cost;
}}}} stack<int>q;
int te= bit-1;
printf ("%d\n", Dp[te].score);
while (TE) {q.push (Dp[te].now);
Te= Dp[te].pre; } while (!
Q.empty ()) {cout<<a[q.top ()].name<<endl;
Q.pop ();
}} return 0;
}