动态规划入门——Doing Homework
2013-10-02 10:10
246 查看
转载请注明出处:http://blog.csdn.net/a1dark
分析:这道题比较坑、本来可以贪心、但是题目要求按照字典序输出、由于贪心会打乱排序、所以不能用、然后是搜索、由于有N等于15、15!条路径、搜索也会超时、怎么优化呢、这是发现2<<15可以用数组装下、于是状压DP就出来了、转化成二进制之后1表示已经做了、0表示未做、目标状态是(1<<n)-1、
分析:这道题比较坑、本来可以贪心、但是题目要求按照字典序输出、由于贪心会打乱排序、所以不能用、然后是搜索、由于有N等于15、15!条路径、搜索也会超时、怎么优化呢、这是发现2<<15可以用数组装下、于是状压DP就出来了、转化成二进制之后1表示已经做了、0表示未做、目标状态是(1<<n)-1、
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 1<<15 #define INF 0xfffffff struct node{ int end,cost; char name[105]; }dot ; struct node1{ int now,pre; int time,ans; }dp ; int n,m; void solve(){ int next,time,ans; for(int i=1;i<=m;i++) dp[i].ans=INF; dp[0].time=0; for(int i=0;i<=m;i++){ for(int j=0;j<n;j++){ if(!(i&(1<<j))){ next=i|(1<<j); time=dp[i].time+dot[j].cost; ans=max(0,time-dot[j].end); ans+=dp[i].ans; if(ans<dp[next].ans){//如果找到更优解 dp[next].time=time; dp[next].ans=ans; dp[next].now=j; dp[next].pre=i; } } } } } void output(int x){ if(x==0)return; output(dp[x].pre); printf("%s\n",dot[dp[x].now].name); } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s%d%d",&dot[i].name,&dot[i].end,&dot[i].cost); m=(1<<n)-1; solve(); printf("%d\n",dp[m].ans); output(m); } return 0; }
相关文章推荐
- 动态规划的入门理解
- 动态规划入门——Super Jumping! Jumping! Jumping!
- 动态规划入门——I NEED A OFFER!
- 很特别的一个动态规划入门教程
- 动态规划之状态压缩dp入门
- 浅显易懂的动态规划入门
- 算法入门4:动态规划
- 01背包问题(动态规划入门)
- 很特别的一个动态规划入门教程
- 动态规划入门(二)DP 基本思想 具体实现 经典题目 POJ1088 POJ1163 POJ1050
- 0-1背包问题(动态规划入门)
- 动态规划入门 COGS1398 最长上升子序列
- 动态规划入门—捡水果
- 动态规划——数位dp入门(二)
- 动态规划入门之LCS(2)
- 动态规划入门-超级楼梯
- 动态规划入门之LCS
- 【算法竞赛入门经典】DAG上的动态规划 例题9-1 UVa1025
- 动态规划入门
- caioj1066:动态规划入门(一维一边推4:护卫队)