动态规划入门之线性动态规划

P1077 [NOIP2012 普及组] 摆花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目的意思已经很明确了,就是说我们有n种花,每种花的数量依次是a1,a2,。。。。。an,问我们摆放m盆的方案数量。我们来想,假设我们只有一种花,它总共有4盆我们要求摆放三盆请问有几种方案,答案显而易见的是一种。在前面的条件上,我们再加上一种花,这种花有一盆,请问摆放三盆的种类数有几种?答案也好想,是2.我们怎么得出的答案。首先我们知道如果我们第二种类的花一个也不摆,那么就是1种方案,而我们摆放一个由于前一种花我们可以放两个,所以又是一种,所以答案加起来就是2.由此引出我们的状态转移方程。


dp的含义是,前c种花凑齐e数量的种类数。
我们可以这么想,我第c种花不取,那么我现在的种类数是前c-1种花凑齐e时的方案数。如果我选择一支花,那就是前c-1种花凑齐e-1时的数量。由此我们得出状态转移方程。
dp[0][0]=1;//当我们有0种话摆放0盆当然只有1种选择
for(c=1;c<=a;c++) {//枚举每个花的品种
	int d=sc.nextInt();//输入每个花的数量
	for(int e=0;e<=b;e++) {//一种花可能会有0种也可能会有n种,我们在这里枚举前c-1种话凑齐数量e
		for(int f=0;f<=Math.min(e, d);f++) {//一种花最后可能数量会超过我们要求的最大m数量,所以在这里我们选取最小值,同时枚举第c种花的数量,当第c种花的数量为3时,他的种类数就为前c-1种花凑齐e-3的种类数。

			dp[c][e]=(dp[c-1][e-f]+dp[c][e])%aa;//如果这种花
		}
	}
}

答案:


import java.awt.FontFormatException;
import java.io.BufferedReader; 
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.AnnotatedWildcardType;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Spliterator.OfPrimitive;
import java.util.function.IntToDoubleFunction;
import java.util.function.LongBinaryOperator;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.management.relation.InvalidRelationTypeException;
import javax.print.attribute.standard.JobMessageFromOperator;
import javax.print.attribute.standard.JobPriority;
import javax.swing.plaf.ColorChooserUI;
import javax.swing.table.TableModel;
import javax.swing.text.TabSet;
import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
public class Main {
  public static void main(String[] args) throws IOException  {
Scanner sc=new Scanner(System.in);
BufferedReader br1=new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw1=new PrintWriter(System.out);

int a=sc.nextInt();
int b=sc.nextInt();
int[][] dp=new int[a+1][b+1];
int c;
dp[0][0]=1;
for(c=1;c<=a;c++) {
	int d=sc.nextInt();
	for(int e=0;e<=b;e++) {
		for(int f=0;f<=Math.min(e, d);f++) {
			dp[c][e]=(dp[c-1][e-f]+dp[c][e])%aa;
		}
	}
}
System.out.println(dp[a][b]);
  }
  public static int aa=(int)(1e6+7); 
 }
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值