This problem thought for a long time, always feel too much state, too many situations, with DP at all do not know how to write
Read the online problem-solving report, said to use a pressure DP, that is, Dp[i] record the minimum number of points to complete which jobs, and then the recursive formula is: Dp[i]=min (Dp[i],max (dp[i-(1<<j)]+max (sum[i]-dead[j],0)) ;
Sum[i] is the time it took to get to that state, Cost[j] indicates the time to spend on the J job, Dead[j] represents the deadline of the J job
Because the state of I is considered, I state can be pushed by several states, that is, the last number of the state added in various order has been taken into account, so as to ensure the accuracy of the formula.
Then say the difference between this problem and the previous several questions, in this problem, from the scale of the former i-1 to the first I problem, because the title of the first problem can be placed in a variety of positions, and each will affect the previous results, so that the recurrence of such a way is not feasible, and the previous Mokey Banana, because the next block is added only to the top layer of the block, so we add an identifier to indicate what the topmost block, which allows the next block to join does not affect the front square of a maximum value. In this problem, we use the minimum value of the number of combinations to make the next state of the join will not affect the previous state, a very ingenious idea.
Seems to write a bit messy, DP is so, a lot of things really can only be understood, can not be said, or want to think more about themselves
#include <stdio.h> #include <string.h> #include <algorithm>using namespace Std;const int inf= 0x7fffffff;const int N=1<<15+10;int dp[1<<15],sum[1<<15],order[1<<15],dead[20],cost[20]; Char s[20][105];void init () {Dp[0]=0;memset (sum,0,sizeof (sum)); memset (order,0,sizeof (Order));} void output (int maxn) {if (maxn==0) Return;int tmp=maxn& (1<<ORDER[MAXN]), Output (maxn-tmp);p rintf ("%s\n", s[ ORDER[MAXN]]);} int main () {#ifndef online_judgefreopen ("In.txt", "R", stdin), #endifint t,n;scanf ("%d", &t), while (t--) {init (); scanf ("%d", &n), int maxn=1<<n;for (int i=0;i<n;i++) scanf ("%s%d%d", S[i],&dead[i],&cost[i]); for (int i=1;i<maxn;i++) {dp[i]=inf;for (int j=0;j<n;j++) {//From Go back to guarantee output when dictionary order is minimum int k=i& (1<<J); if (k) {sum[i]=sum[i-(1<<j)]+ Cost[j];int tmp=dp[i-(1<<j)]+max (sum[i]-dead[j],0); if (Tmp<=dp[i]) {dp[i]=tmp;order[i]=j;}}} maxn--;p rintf ("%d\n", Dp[maxn]),//for (int i=1;i<=maxn;i++) printf ("%d\n", dp[i]); output (MAXN);} Return0;}
HDU 1074 Doing Homework