题目描述
在 x = □ 1 □ 2 □ 3 □ 4 □ 5 □ 6 □ 7 □ 8 □ 9 x=\square1\square2\square3\square4\square5\square6\square7\square8\square9 x=□1□2□3□4□5□6□7□8□9 的 □ \square □ 内填入 + + + 或 − - −.
(1) 求证: 27 27 27 可以被这样表示, 28 28 28 不可以.
(2) 求 x = 7 x=7 x=7 时的方案数。
题解
(1) 求证: 27 27 27 可以被这样表示, 28 28 28 不可以.
证明: 27 = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 − 9 27=1+2+3+4+5+6+7+8-9 27=1+2+3+4+5+6+7+8−9,可以被表示
设填入 − - − 后的数字的总和为 S S S,
则 x = ( ( 1 + 2 + . . . + 9 ) − S ) − S = 45 − 2 S x=((1+2+...+9)-S)-S=45-2S x=((1+2+...+9)−S)−S=45−2S
∵ S \because S ∵S 为整数
∴ 2 S \therefore 2S ∴2S 为偶数
∴ 45 − 2 S \therefore 45-2S ∴45−2S 为奇数,即 x x x 为奇数
∵ 28 \because 28 ∵28 为偶数
∴ 28 \therefore 28 ∴28 不可以被表示
(2) 求 x = 7 x=7 x=7 时的方案数。
这题我们可以用一个比较 OI \text{OI} OI 的方法—— DP \text{DP} DP(动态规划)。
定义 f i , j f_{i,j} fi,j 表示已经填了 i i i 个方格,答案为 j j j 的情况下的方案数。
很显然, f 0 , 0 = 1 f_{0,0}=1 f0,0=1.
递推式也非常简单: f i , j = f i − 1 , j − i + f i − 1 , j + i f_{i,j}=f_{i-1,j-i}+f_{i-1,j+i} fi,j=fi−1,j−i+fi−1,j+i.
然后就手推到 f 9 , 7 f_{9,7} f9,7 就可以了,
表格如下(空格子表示值为 0 0 0):
即:方案数为 f 9 , 7 = 21 f_{9,7}=21 f9,7=21.
计算量比较大,这里我直接用代码写了,由于下标为负数可能会出错,所以把下标统一加上 200 200 200:
#include<bits/stdc++.h>
using namespace std;
int f[405][405];
int main(){int n=9;f[0][200]=1;for(int i=1;i<=n;i++){for(int j=-55;j<=55;j++){f[i][j+200]=f[i-1][j+200-i]+f[i-1][j+200+i];}}cout<<f[n][200+7]<<endl;return 0;
}
最终算出答案为 21 21 21。
虽然这也比较麻烦,但比枚举快多了。