HDU 1074 Doing Homework

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1074

题意:给一些作业,并给出每个作业的截止日期和完成需要时间,每迟一天扣1分,求最少要扣多少分

可以根据当前的状态判断应该扣多少分

题目给出的是字典序,所以输出答案时应该倒着枚举

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
struct p
{
    string name;
    int x,y;
}a[15];
int dp[1<<15];
int n;
int f(int x,int y)
{
    int s=a[y].y;
    int t=0;
    while(x)
    {
        if (x&1)
            s+=a[t].y;
        x>>=1;
        t++;
    }
    if (a[y].x<s)
        return s-a[y].x;
    return 0;
}
void dfs(int x)
{
    if (x==0) return;
    for(int i=n-1;i>=0;i--)
    {
        if ((x>>i)&1)
        {
            if (dp[x^(1<<i)]+f(x^(1<<i),i)==dp[x])
            {
                dfs(x^(1<<i));
                cout<<a[i].name<<endl;
                return;
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i].name>>a[i].x>>a[i].y;
        int tot=1<<n;
        memset(dp,0x3f,sizeof(dp));
        dp[0]=0;
        for(int i=0;i<tot;i++)
        {
            for(int j=0;j<n;j++)
            {
                if ((i>>j)&1) continue;
                dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+f(i,j));
            }
        }
        cout<<dp[tot-1]<<endl;
        dfs(tot-1);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/bk-201/p/7467462.html