Week12 作业E - 选做题 - 2

1.题意

马上假期就要结束了,zjm还有 n 个作业,完成某个作业需要一定的时间,而且每个作业有一个截止时间,若超过截止时间,一天就要扣一分。
zjm想知道如何安排做作业,使得扣的分数最少。
Tips: 如果开始做某个作业,就必须把这个作业做完了,才能做下一个作业。

2.样例

Input

有多组测试数据。第一行一个整数表示测试数据的组数
第一行一个整数 n(1<=n<=15)
接下来n行,每行一个字符串(长度不超过100) S 表示任务的名称和两个整数 D 和 C,分别表示任务的截止时间和完成任务需要的天数。
这 n 个任务是按照字符串的字典序从小到大给出。

Output

每组测试数据,输出最少扣的分数,并输出完成作业的方案,如果有多个方案,输出字典序最小的一个。

Sample Input

2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3

Sample Output

2
Computer
Math
English
3
Computer
English
Math

Hint

在第二个样例中,按照 Computer->English->Math 和 Computer->Math->English 的顺序完成作业,所扣的分数都是 3,由于 English 的字典序比 Math 小,故输出前一种方案。

3.解题思路

  1. 对于n种家庭作业,全部做完有n!种做的顺序,太大了,考虑状态压缩,dp[i]记录到达状态i所扣的分数,t[i]记录到达状态i所花的时间
  2. 对于状态i,从何种状态到达i ?,只需要枚举所有的作业,如对作业k,i中已经有k完成,则i可以由和i相同的状态,仅仅是K未完成的状态j=i-(1<<k)来完成k的到达,且j一定比i 小从状态0枚举到2^n-1,则j一定是在i之前算过的
  3. 先枚举状态,再倒序枚举j,因为要保证字典序,j从大到小,因为每次完成j相当于把j放在后面完成,它的上一状态则从小到大,则输出的为字典序最小的那个

4.AC代码

#include<stdio.h>
#include<algorithm>
#include<stack>
#include<iomanip>
#include<iostream>
#include<cstring>
using namespace std;
const int M=(1<<15)+5;
const int INF=1e8;
int n;
int dp[M],t[M],pre[M],f[20],d[20];
char s[20][105];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(s,0,sizeof(s));
		memset(t,0,sizeof(t));
		memset(pre,0,sizeof(pre));
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%s%d%d",&s[i],&d[i],&f[i]);
		}
		int bit=(1<<n)-1;
		for(int i=1;i<=bit;i++)
		{
			dp[i]=INF;
			for(int j=n-1;j>=0;j--)
			{
				int tmp=(1<<j);
				if(!(i&tmp)) continue;
				int score=t[i-tmp]+f[j]-d[j];
				if(score<0) score=0;
				if(dp[i]>dp[i-tmp]+score)
				{
					dp[i]=dp[i-tmp]+score;
					t[i]=t[i-tmp]+f[j];
					pre[i]=j;
				}
			}
		}
		printf("%d\n",dp[bit]);
		stack<int>st;
		st.push(pre[bit]);
		while(bit-(1<<pre[bit])!=0)
		{
			bit-=(1<<pre[bit]);
			st.push(pre[bit]);
		}
		while(!st.empty())
		{
			printf("%s\n",s[st.top()]);
			st.pop();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在第4周的可重复研究目中,我将继续探索如何使用开放源代码工具和技术来实现可重复性和透明度。 首先,我将继续使用版本控制系统(如Git),以便跟踪我研究目中的所有更改和改进。这将确保我能够回溯到每个版本的数据和代码,并对目进行可重复性验证。在本周内,我还将学习更多关于Git分支和合并的知识,以便更好地组织和管理我的目。 另外,我还将使用Jupyter Notebook来记录我的实验过程和结果。Jupyter Notebook提供了一个互动环境,可以将代码、文档和图形化结果结合在一起,使得我的研究成果更加易于理解和重现。我会确保我的Notebook中包含了所有必要的步骤和解释,以便他人能够准确地复现我的研究。 为了进一步提高可重复性,我还将采取一些数据预处理和清洗的措施。这些措施包括去除异常值、处理缺失数据和标准化数据等。我将确保我的数据处理过程明确记录,并提供相应的代码和文档,以便他人能够按照相同的步骤进行处理。 最后,我还计划使用容器化技术(如Docker)来实现我的研究目的可移植性。通过将我的环境和依赖封装在一个容器中,我可以确保其他人能够在不同的计算机和操作系统上轻松地运行我的代码和分析。 综上所述,第4周的可重复研究目将继续探索一系列工具和技术,旨在提高我的研究目的可重复性和透明度。通过使用版本控制系统、Jupyter Notebook、数据处理和清洗措施以及容器化技术,我将确保我的研究成果可以被其他人准确地重现和验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值