hdu 1074
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1074相关的知识,希望对你有一定的参考价值。
状态压缩题,要注意的是有多种情况扣分相同,那么要按照字典序输出,也就是输入时在前,那么输出也要在前。具体看代码注释。参考文章:
- http://www.voidcn.com/article/p-fsgosnqv-bpb.html
- http://www.cnblogs.com/kuangbin/archive/2011/08/04/2127687.html
- http://www.cnblogs.com/qkhhxkj/archive/2011/06/29/2093894.html
#include <iostream>
#include <stdio.h>
#include <string>
#include <stack>
using namespace std;
const int maxn=1<<17;
struct homework{
char name[150];
int deadline;
int timecost;//做作业所花费的时间
}h[30];
struct node{
int score;//当前的扣分情况
int time;//当前所花的天数
int num;//当前所做作业的序号
int pre;//上一个状态的地址
}dp[maxn];//数组要开的足够大,数字上限为2^n
int main(){
int T,N;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
for(int i=0;i<N;i++) scanf("%s%d%d",&h[i].name,&h[i].deadline,&h[i].timecost);
dp[0].score=0;
dp[0].time=0;
int M=(1<<N)-1;
for(int i=1;i<=M;i++){//用二进制的0~n-1位来表示作业1~n的完成情况,0为都没有完成,(1<<N)-1表示所有作业都完成,这里进行遍历
dp[i].score=100000;//保证dp[i]得到初始化
for(int j=N-1;j>=0;j--){//j从大到小每个作业遍历,保证字典序输出
int temp=1<<j;
if((i&temp)==temp){//表示当前作业状态是做了j号作业的
int k=i-temp;//表示上一个状态,也就是没有做j号作业,其余与这个状态一样
int x=dp[k].time+h[j].timecost-h[j].deadline;
if(x<0)
x=0;//计算做j号作业是否逾期,若没有预期逾期则不扣分
if(dp[k].score+x<dp[i].score){//若为扣分最少的情况,则更改信息
dp[i].score=dp[k].score+x;
dp[i].num=j;
dp[i].time=dp[k].time+h[j].timecost;
dp[i].pre=k;
}
}
}
}
printf("%d\n",dp[M].score);
stack<int>st;
while(M!=0){
st.push(dp[M].num);
M=dp[M].pre;
}
while(!st.empty()){
printf("%s\n",h[st.top()].name);
st.pop();
}
}
return 0;
}
确实不是很懂这题,出错的地方请见谅。
以上是关于hdu 1074的主要内容,如果未能解决你的问题,请参考以下文章