UVAoj 11806 - Cheerleaders

题解:
1.汝佳哥容斥的漂亮
2.我是分情况讨论的,所有情况抛去有一条(行或者列)没有石子的,再抛去两条,三条,和四条的
总结:
1.除了那些特别有把握的题目以外,都要尝试一些小的数据。
2.思考问题时要整齐的用草稿纸,以保证良好的解题思路!

我的代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 505
#define MOD 1000007
int n,m,k,_,c[MAXN][MAXN];
int solve()
{
    if(k > n * m)return 0;
    int minn = c[(m - 2) * (n - 2)][k];
    int a1 = 2 * (c[(n - 1) * (m - 2)][k] - minn);
    int a2 = 2 * (c[(n - 2) * (m - 1)][k] - minn);
    int b1 = c[n * (m - 2)][k] - minn - a1;
    int b2 = c[(n - 2) * m][k] - a2 - minn;
    int c1 = 4 * (c[(m - 1) * (n - 1)][k] - a1 / 2 - a2 / 2 - minn);
    int d1 = 2 * (c[m * (n - 1)][k] - b2 - a1 / 2 - a2 - c1 / 2 - minn);
    int d2 = 2 * (c[(m - 1) * n][k] - b1 - a2 / 2 - a1 - c1 / 2 - minn);
    return ((c[n * m][k] - a1 - a2 - b1 - b2 - c1 - d1 - d2 - minn) % MOD + MOD) % MOD;
}
int main()
{
    scanf("%d",&_);
    for(int i = 0;i < MAXN;i++)c[i][0] = 1;
    for(int i = 1;i < MAXN;i++)
        for(int j = 1;j < MAXN;j++)
            c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
    int kcas = 0;
    while(_--)
    {
        scanf("%d%d%d",&n,&m,&k);
        int ans = solve();
        printf("Case %d: %d\n",++kcas,ans);
    }
}

汝佳哥的代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 505
#define MOD 1000007
int n,m,k,_,c[MAXN][MAXN];
int solve()
{
    if(k > n * m)return 0;
    int ans = 0;
    for(int i = 0;i < 16;i++)
    {
        int a = n,b = m,d = 0;
        if(i & 1)
        {
            a--;
            d++;
        }
        if(i & 2)
        {
            a--;
            d++;
        }
        if(i & 4)
        {
            b--;
            d++;
        }
        if(i & 8)
        {
            b--;
            d++;
        }
        if(d & 1)ans -= c[a * b][k];
        else ans += c[a * b][k];
    }
    //cout << ans << " ans " << endl;
    return (ans % MOD + MOD) % MOD;
}
int main()
{
    scanf("%d",&_);
    for(int i = 0;i < MAXN;i++)c[i][0] = 1;
    for(int i = 1;i < MAXN;i++)
        for(int j = 1;j < MAXN;j++)
            c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
    int kcas = 0;
    while(_--)
    {
        scanf("%d%d%d",&n,&m,&k);
        int ans = solve();
        printf("Case %d: %d\n",++kcas,ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值