## 蓝桥杯 算法提高VIP 摆花 dp 记忆搜索 2种做法

```2  4
3  2 ```

```2
```

``````import java.util.Scanner;

public class 摆花_记忆搜索 {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
memo = new int[n+5][m+5][m+5];
a = new int[n+5];
for(int i=1;i<=n;i++)
a[i] = in.nextInt();

System.out.println(f(n,m,0));
}
static int[] a;
static int[][][] memo;

static int f(int n,int m,int k) {
if(n<0)
return 0;
if(memo[n][m][k]!=0)
return memo[n][m][k];
if(k>a[n])
return 0;
if(m==0)
return 1;
memo[n][m][k] = (f(n,m-1,k+1) + f(n-1,m,0))%1000007;
return memo[n][m][k];
}

}
``````

``````import java.util.Scanner;

public class 摆花_记忆搜索2 {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
memo = new int[n+5][m+5];
a = new int[n+5];
for(int i=1;i<=n;i++)
a[i] = in.nextInt();

System.out.println(f(n,m));
}
static int[] a;
static int[][] memo;

static int f(int n,int m) {
if(memo[n][m]!=0)//可以初始化-1,防止记忆退化,100的数据规模就没必要了
return memo[n][m];

if(n==0)
return m==0?1:0;
for(int i=0;i<=Math.min(m, a[n]);i++)//递归思路,把当前第n种花，在不超过质量m的情况下,取0,1,2,3,...,a[n],把所有情况的答案累加起来
memo[n][m] = (memo[n][m] + f(n-1,m-i))%1000007;

return memo[n][m];
}

}
``````

dp做法，一直感觉这种是背包问题，hhh，有误区，这里说下，背包是每取一个都有价值，这个是取到满质量了记为一种情况，所以还是有本质区别的，意思是只有出口有值为1~

``````import java.util.Scanner;

public class 摆花_dp {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[][] dp = new int[n+5][m+5];
int[] a = new int[n+5];
for(int i=1;i<=n;i++)
a[i] = in.nextInt();
dp[0][0] = 1;

for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=Math.min(j,a[i]);k++)
dp[i][j] = (dp[i][j] + dp[i-1][j-k])%1000007;

System.out.println(dp[n][m]);
}

}
``````

0条评论