标签:dp
2 3 Computer 3 3 English 20 1 Math 3 2 3 Computer 3 3 English 6 3 Math 6 3
2 Computer Math English 3 Computer English MathHintIn 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.
/* 读完题目后想的和此博客人想法大致一样 http://www.cnblogs.com/Kenfly/archive/2011/03/30/2000364.html 可是,感觉有一个问题,因为担心会出现 a,b都可以到c 虽然a到c的花费大 ,但是a可能时间短,因为此时间对后面有影响,a可能后面会反败为胜呢? 感觉这样不好处理,百度却找不到解答,最后自己想通了,原来既然状态相同,那么花费的时间是一样的, 这样疑惑顿时没有了 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y) ((x+y)>>1) #define bug printf("hihi\n") #define eps 1e-8 typedef __int64 ll; using namespace std; #define INF 0x3f3f3f3f #define N 16 struct stud{ int pre,time;//当前状态是由哪一个点来的,当前状态时间, int score;//当前扣得分数 }dp[1<<16]; struct ha{ string name; int d,len; }home[N]; int n; void show(int st) { if(st==0) return ; show(st^(1<<dp[st].pre)); cout<<home[dp[st].pre].name<<endl; } void DP() { int len=1<<n; int i,j; for(i=0;i<len;i++) dp[i].score=INF; dp[0].score=0; dp[0].time=0; dp[0].pre=-1; for(i=0;i<len;i++) for(int j=0;j<n;j++) { if(i&(1<<j)) continue; int to=i|(1<<j); int time=dp[i].time+home[j].len; int score=0; if(time>home[j].d) score=time-home[j].d; score+=dp[i].score; if(dp[to].score>score) { dp[to].score=score; dp[to].pre=j; dp[to].time=time; // printf("%d: %d %d %d\n",to,to^(1<<j),dp[to].score,dp[to].time); } } printf("%d\n",dp[len-1].score); show(len-1);//递归输出路径 } int main() { int i,j; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { cin>>home[i].name>>home[i].d>>home[i].len;//字典序输入,无需排序 } DP(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:dp
原文地址:http://blog.csdn.net/u014737310/article/details/47134165