动态规划专栏(1)【摆花+平方数+神犇分牛】

来源:互联网 发布:python 接口 编辑:程序博客网 时间:2024/05/01 15:08

前言:

对于动态规划来说,是小学乃至初中非常难的一类题型,状态转移方程是非常的难推,现在开始,我开了一个动归专栏。

                                                                                   



                                    (1)摆花(flower.pas)                    

 {
  题目: N 盆花中共有 M 种花,从 1 到 n 标号。为了展出更多种花, 规定第 i 种花不能超过 ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到 大的顺序依次摆列。 
  试编程计算,一共有多少种不同的摆花方案。
  解题思路:已知i号花有ai个,所以三重循环分别枚举:
  数量M、种数N、和当前的数量a[]
  对于新来的花I,我们把它暂且看成未知数K(<=a[i])
}



STD:
var
  n,m,i,j,k:longint;
  f:array[0..100,0..100] of longint;//i为数量,j为当前数量的最优放花的种数
  a:array[1..10000] of longint;
begin
  readln(n,m);
  for i:=1 to n do
    read(a[i]);
  f[0,0]:=1;//0盆花中有0种花,只有一种方法。
  for i:=1 to n do//枚举N
    for j:=m downto 0 do//枚举M,downto快一些
      for k:=0 to a[i] do//枚举第i种花的数量(也可不取这盆花)
      if j-k>=0 then//保证有解
        f[i,j]:=(f[i,j]+f[i-1,j-k]) mod  1000007;
//当前状态=当前转移+【j-k:(j:上一种;k:上一些)没有用到这些花】
  writeln(f[n,m]);//N盆、M种
end.    

                                     (2)平方数 (sqr.pas)  

 { 
  题目:对任意的正整数n,
  把它分解为几个整数的平方之和(不包含零),
  有多少种方案?
  解题思路:三重循环分别枚举总数、当前平方数(末尾)、
  一共有几种<=当前的平方数的数
  样例说明:n=4
  4=1*1+1*1+1*1+1*1 当前和=4,末尾=1*1;
}



STD:
 var
  n,m,i,j,k:longint;
  a:array[1..1000] of longint;
  f:array[0..800,0..800] of longint;//分别表示当前的总和和当前方案末尾的数
begin
  readln(n);
  f[0,1]:=1;//总数是零,当前末尾为1,只有一种方式。
  for i:=1 to n do//枚举总和
    for j:=1 to trunc(sqrt(n)) do//枚举sqrt(n)的平方数,上取整。
      for k:=1 to j do
      if i>=j*j then//保证有解
      f[i,j]:=f[i,j]+f[i-j*j,k];//当前状态=当前转移+【当前总和排除当前平方数,现在新的末尾】
    for i:=1 to  trunc(sqrt(n)) do
      m:=m+f[n,i];//把所有等于n的方案加起来
    writeln(m);
end.     

                                      (3)神犇分牛(cows.pas)

 {
题目:把m头牛放进n个房间,房间可以空着
问:总共有多少种方法(一共t次询问),答案可能较大,%100000007
思路:枚举一个房间中可能放牛的数量i,剩下的房间(k-1)可放牛的数量为j-i
}



STD:
var
i,j,m,n,k,t,p:longint;
f,f1:array[0..300,0..300] of longint;
begin
  readln(t);
  for p:=1 to t do
  begin
readln(m,n);
    f:=f1;
    f[0,0]:=1;
 for i:=0 to m do//一个房间的奶牛数
 for j:=i to m do//奶牛总数
 for k:=1 to n do//房间总数
 f[j,k]:=(f[j,k]+f[j-i,k-1]) mod 100000007;
//当前状态=当前转移+【总房间放牛数-一个房间已经放牛数,那就少放一个房间】
 writeln(f[m,n]);
  end;
end.



                  

原创粉丝点击