第一种解法是很经典的动态规划,对于值域较小的题目,还可以采用第二种方法,考虑对值域空间-即对容积的可达性进行动态规划。

这道题里面采用第二种解法还会有空间上的优化。

有时把值域作为一种状态不单单是一种解法,还有可能是唯一的解法。如HDU 1574 RP问题

描述

有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。

输入

输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。

输出

输出不同的选择物品的方式的数目。

 

动规解法:

人人为我

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 int dp[45][45];        //dp[i][j]表示前j件物品总体积是i的方案总数
 8 int a[45];
 9 
10 int main(void)
11 {
12     #ifdef LOCAL
13         freopen("2755in.txt", "r", stdin);
14     #endif
15 
16     int n;
17     scanf("%d", &n);
18     dp[0][0] = 1;
19 
20     int i;
21     for(i = 1; i <= n; ++i)
22     {
23         scanf("%d", &a[i]);
24         dp[0][i] = 1;
25     }
26     int j;
27     for(i = 1; i <= 40; ++i)
28         for(j = 1; j <= n; ++j)
29         {
30             dp[i][j] = dp[i][j-1];
31             if(a[j] <= i)
32                 dp[i][j] += dp[i-a[j]][j - 1];
33         }
34     printf("%d\n", dp[40][n]);
35     return 0;
36 }
代码君

相关文章:

  • 2022-02-24
  • 2022-12-23
  • 2022-12-23
  • 2021-07-09
  • 2021-09-10
  • 2021-04-24
  • 2021-10-01
  • 2021-12-16
猜你喜欢
  • 2021-07-19
  • 2022-01-10
  • 2022-12-23
  • 2021-12-12
  • 2021-12-07
  • 2022-12-23
  • 2021-11-21
相关资源
相似解决方案