洛谷 P2392 kkksc03考前临时抱佛脚dp/搜索

本文介绍了在一维和二维版本的背包问题中,使用动态规划(dp)以及搜索算法求解解题思路,提供了C++代码示例,探讨了如何在给定时间限制下选择题目以最大化收益。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目链接

链接: P2392 kkksc03考前临时抱佛脚

题目描述

在这里插入图片描述

解题思路

dp或者搜索

代码实现

01背包二维版本

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=25;
int f[N][2000];//只考虑前i个题,使用j 题目时间小于j 消耗最长时间 
int s[4],res=0;
int a[N];
int main()
{
   ios::sync_with_stdio(0);
   cin.tie(0),cout.tie(0);
   int T=4;
   for(int i=0;i<4;i++) cin>>s[i];
   while(T--)
   {
       int n=s[4-T-1];
       int sum=0; 
   	   for(int i=1;i<=n;i++){
   	     	cin>>a[i];
   	     	sum+=a[i];
	   } 
   	   for(int i=1;i<=n;i++)
   	   {
   	      for(int j=0;j<=sum/2;j++)
        	 {
        	     f[i][j]=f[i-1][j];
        	     if(j>=a[i])
		   	 	 f[i][j]=max(f[i][j],f[i-1][j-a[i]]+a[i]);
		     } 	
	   }
	   res+=sum-f[n][sum/2];
   }
   cout<<res;
   return 0;	
}

一维版本

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=25;
int f[2000];//只考虑前i个题,使用j 题目时间小于j 消耗最长时间 
int s[4],res=0;
int a[N];
int main()
{
   ios::sync_with_stdio(0);
   cin.tie(0),cout.tie(0);
   int T=4;
   for(int i=0;i<4;i++) cin>>s[i];
   while(T--)
   {
       int n=s[4-T-1];
       int sum=0; 
   	   for(int i=1;i<=n;i++){
   	     	cin>>a[i];
   	     	sum+=a[i];
	   } 
   	   for(int i=1;i<=n;i++)
   	   {
   	      for(int j=sum/2;j>=a[i];j--)
        	 {
		   	 	 f[j]=max(f[j],f[j-a[i]]+a[i]);
		     } 	
	   }
	   res+=max(f[sum/2],sum-f[sum/2]);
	   memset(f,0,sizeof f);
   }
   cout<<res;
   return 0;	
}

搜索

#include<bits/stdc++.h>
using namespace std;
int Left,Right,minn,ans;
int s[5];
int a[21][5];
void search(int x,int y){
	if(x>s[y]){
		minn=min(minn,max(Left,Right));
		return;
	}
	Left+=a[x][y];
	search(x+1,y);
	Left-=a[x][y];
	Right+=a[x][y];
	search(x+1,y);
	Right-=a[x][y];//毫无技巧的搜索回溯
}
int main(){
	cin>>s[1]>>s[2]>>s[3]>>s[4];
	for(int i=1;i<=4;i++){//减少码量
		Left=Right=0;
		minn=19260817;
		for(int j=1;j<=s[i];j++)
			cin>>a[j][i];
		search(1,i);
		ans+=minn;
	}
	cout<<ans;
	return 0;
}

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值