[BZOJ1643]&&[Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪

描述 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


BZOJ 1643


代码 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;
}