CCF CSP 202209-2何以包邮

文章讲述了如何使用动态规划方法解决0/1背包问题,通过构建一维滚动数组dp来高效计算,给出了一个C++代码示例。
摘要由CSDN通过智能技术生成

题目

试题编号202209-2
试题名称何以包邮
时间限制1s
内存限制512MB
问题描述在这里插入图片描述
输入输出在这里插入图片描述
样例1在这里插入图片描述
样例2在这里插入图片描述
样例3在这里插入图片描述

题目分析

动态规划。就是一个0/1背包问题。 d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i本书,在超过总钱数为j情况下的最小钱数目。
j < p r i c e i j<price_i j<pricei,则:
d p [ i ] [ j ] = m i n ( p r i c e i , d p [ i − 1 ] [ j ] ) dp[i][j]=min(price_i,dp[i-1][j]) dp[i][j]=min(pricei,dp[i1][j])
j > = p r i c e i j>=price_i j>=pricei,则:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − p r i c e i ] + p r i c e i , d p [ i − 1 ] [ j ] ) dp[i][j]=min(dp[i-1][j-price_i]+price_i,dp[i-1][j]) dp[i][j]=min(dp[i1][jpricei]+pricei,dp[i1][j])
可以看到dp的更新只基于前一行且有从后往前更新的顺序,那么可以用一维滚动数组dp[300000]直接计算。

AC代码(100分)

#include <stdio.h>
#include <algorithm>
#include <string.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define min(a,b) ((a)<(b)?(a):(b))
int n,x;
int a;
int dp[300000];
int ans=0;
int main(){
	scanf("%d%d",&n,&x);
	memset(dp,0x3f,sizeof(dp));
	rep(i,0,n){
		scanf("%d",&a);
		ans+=a;
		for(int j=ans;j>0;j--){
			if(j>a)dp[j]=min(dp[j],dp[j-a]+a);
			else dp[j]=min(dp[j],a);
		}
	}
	printf("%d",dp[x]);
	return 0;
}
/*
4 10
2
9
6
6
*/
  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值