递归和动态规划两种做法。本来以为可以用贪心,结果好像不太行
题目描述
这次期末考试,kkksc03 需要考 44 科。因此要开始刷习题集,每科都有一个习题集,分别有 s1,s2,s3,s4 道题目,完成每道题目需要一些时间,可能不等(A1,A2,…,As1,B1,B2,…,Bs2,C1,C2,…,Cs3,D1,D2,…,Ds4)。
kkksc03 有一个能力,他的左右两个大脑可以同时计算 22 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。要求时间所用最短
输入格式
本题包含 5 行数据:第 11 行,为四个正整数 s1,s2,s3,s4。
第 2 行,为 1A1,A2,…,As1 共 s1 个数,表示第一科习题集每道题目所消耗的时间。
第 3 行,为 B1,B2,…,Bs2 共 s2 个数。
第 4 行,为 C1,C2,…,Cs3 共 s3 个数。
第 5 行,为D1,D2,…,Ds4 共 s4 个数,意思均同上。
输出格式
输出一行,为复习完毕最短时间。
输入输出样例
输入 #1复制
1 2 1 3 5 4 3 6 2 4 3输出 #1复制
20
递归:
#include<bits/stdc++.h>
using namespace std;
int s[5]={0};
int num[5][25]={0};
int mint=1000000;
int L=0,R=0;
int sum=0;
void dfs(int k,int t){
if(s[k]+1==t){
mint=min(mint,max(L,R));
return ;
}
L+=num[k][t];
dfs(k,t+1);
L-=num[k][t];//开始回溯
R+=num[k][t];
dfs(k,t+1);
R-=num[k][t];//又一次回溯
}
int main()
{
cin>>s[1]>>s[2]>>s[3]>>s[4];
for(int i=1;i<=4;i++){
for(int j=1;j<=s[i];j++){
cin>>num[i][j];
}
mint=1000000;//重置初值
L=R=0;
dfs(i,1);
sum+=mint;
}
cout<<sum;
return 0;
}
01背包动态规划:当左右两边时间相同时,所用时间最短,所以取每一科总时间的一半作为01背包容量
#include<bits/stdc++.h>
using namespace std;
int s[4];
int num[30];
int dp[21][1000];
int main(){
for(int i=0;i<4;i++) {
cin>>s[i];
}
int sum=0;
for(int i=0;i<4;i++){
int tmp=0;
for(int j=1;j<=s[i];j++){
cin>>num[j];
tmp+=num[j];//把一科所有作业的时间加和
}
int t=0;
for(int j=1;j<=s[i];j++)
for(int k=1;k<=tmp/2;k++){
if(k>=num[j]){//大于则选择
dp[j][k]=max(dp[j-1][k],dp[j-1][k-num[j]]+num[j]);
}
else{//小于则不选, 等于上一次的值
dp[j][k]=dp[j-1][k];
}
t=dp[j][k];
}
sum+=max(t,tmp-t);//每一科作业所用时间最大值加和
}
cout<<sum<<endl;
return 0;
}
嘻嘻~,又有些许的长进,感觉日子越来越有盼头了
文章展示了使用递归和动态规划解决具体问题的代码实例,以及如何通过01背包思想优化kkksc03考试的复习时间。

2769

被折叠的 条评论
为什么被折叠?



