蓝桥杯0013 Too easy to dp

Description

Mr Zhou准备了一块nm的巧克力想分给301的小(da)朋友们,强迫症的他想沿着纹路掰成恰好nm个11的小块。
每次他只能拿起一块巧克力,并沿着纹路掰断,这称为一次操作(比如一块3
4的,一次操作可以掰成两块32的,也可以是31和33的,还可以掰成14和24的)。
经过精密的计算,他算不出最少要掰几次…于是拜托你来算。
现实是残酷的,掰巧克力的时候很难按纹路完美掰成1
1的,一番努力之后,Mr Zhou只得到了一堆(k块)不规则形状的巧克力碎片。
更不幸的是,301只有sorahjy一个人在努力学(hua)习(shui),Mr Zhou只好和sorahjy一起分而食之。
经过精密的计算,他们算不出怎么尽量平分这些巧克力…于是又拜托你来算。
尽量平分的定义是使得两个人最后的得到的巧克力,质量差的绝对值最小,当然所有巧克力都要被吃完啦,不能剩。

Input

第一行 n m k(1<=n,m<=1000 1<=k<=20)
第二行 k个正整数,表示巧克力碎块的大小,保证碎块大小之和为n*m

Output

第一行,将nm的巧克力块掰成nm个1*1小块所需的最少次数
第二行,将k块巧克力尽量平分后,两人巧克力大小之差的绝对值

Sample Input 1

2 3 4
1 2 1 2

Sample Output 1

5
0

Sample Input 2

10 1 4
6 2 1 1

Sample Output 2

9
2

题解

dp苦手
简单dp。巧克力每掰一次块数+1,掰成nm块,需nm-1次。动态规划状态转移方程:dp[j]=max(dp[j],dp[j-a[i]]+a[i])(其核心为01背包计算最大值)

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
	static int n,m,k,s1,s2;
	static int dp[]=new int[1000001]; 
	public static void main(String[] args){
		Scanner sc=new Scanner(new BufferedInputStream(System.in));
		n=sc.nextInt();
		m=sc.nextInt();
		k=sc.nextInt();
		int a[]=new int[k];
		
		for(int i=0;i<k;i++) a[i]=sc.nextInt();
		System.out.println(n*m-1);
		for (int i = 0; i < k; i++) {
			for(int j=n*m/2;j>=a[i];j--){
				dp[j]=Math.max(dp[j],dp[j-a[i]]+a[i]);
			}
		}
		System.out.println(Math.abs(dp[n*m/2]-(n*m-dp[n*m/2])));
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值