描述 Description
农夫约翰已经从他的牧场中取得了数不清块数的正方形草皮,草皮的边长总是整数(有时农夫约翰割草皮的刀法不合适,甚至切出了边长为 0 的正方形草皮),他已经把草皮放在了一个奶牛贝茜已经知道的地方。 贝茜总是希望把美味的草皮放到她的秘密庄园里,她决定从这些草皮中取出恰好 4 块搬到她的秘密庄园中,然后把它们分成 1×1 的小块,组成一个面积为 N(1<=N<=10,000)个单位面积的部分。 贝茜对选出这样四块草皮的方法数很感兴趣,如果她得到了一个 4 个单位面积的部分,那么她可以有 5 中不同的方法选 4 块草皮:(1,1,1,1),(2,0,0,0),(0,2,0,0),(0,0,0,2). 顺序是有效的:(4,3,2,1)和 (1,2,3,4) 是不同的方法。
输入格式 InputFormat
第一行:一个单独的整数 N。
输出格式 OutputFormat
单独的一行包含一个整数,表示贝茜选四块草皮的方案数。
样例输入 SampleInput
10000
样例输出 SampleOutput
1217
来源 Source
Silver
代码 Code
f[i][j]表示用 j 块草皮组成面积 i 的方案数。当且仅当 i 为完全平方数时 f[i][1]=1. 状态转移为 \[f[i][j]=\sum_{k=0}^{\sqrt{i}}f[i-k^{2}][j-1]\].
其实 \(O(n^{2})\) 枚举或者打表也是可以过的。。。
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int f[10005][4];
int i,j,t,n,m,l,r,k,z,y,x,ans;
int main()
{
scanf("%d",&n);
for (i=1;i<=4;i++) f[0][i]=1;
for (i=1;i<=n;i++)
{
t=sqrt(i);
if (t*t==i) f[i][1]=1;
for (j=2;j<=4;j++)
{
for (k=0;k<=t;k++)
{
f[i][j]+=f[i-k*k][j-1];
}
}
}
printf("%d\n",f[n][4]);
return 0;
}