【noi 2.6_666】放苹果 & 【noi 2.6_8467】鸣人的影分身(DP)
这题其实在2.6前面的专题也有出现过,我还以为我有写,结果发现,并没有。于是就现在写了。这2题其实重复了......我就按放苹果的来说。
题意:把N个苹果放在M个盘子里,允许有的盘子空着不放,问共有多少种不同的分法。
解法:f[i][j]表示把 i 个苹果放在 j 个盘子的方案数,分有空盘子和无空盘子的情况DP。
(1)至少有1个空盘子:f[i][j]=f[i][j-1]
(2)没有空盘子:i≥j,则再 +f[i-j][j]。
而对于f[i-j][j]有 2 种理解——所有盘子中都取走1个苹果的方案数,或先各用1个苹果把所有盘子填满再放苹果的方案数。--至于这里为什么是“1”就要想想动态规划的基本性质了。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 int f[15][15]; 8 9 int main() 10 { 11 int T; 12 scanf("%d",&T); 13 while (T--) 14 { 15 int n,m; 16 scanf("%d%d",&n,&m); 17 memset(f,0,sizeof(f)); 18 for (int j=0;j<=m;j++) f[0][j]=1; 19 for (int i=1;i<=n;i++) 20 for (int j=1;j<=m;j++) 21 { 22 f[i][j]=f[i][j-1]; 23 if (i>=j) f[i][j]+=f[i-j][j]; 24 } 25 printf("%d\n",f[n][m]); 26 } 27 return 0; 28 }