Game on Sum (Easy Version)

12 篇文章 0 订阅
3 篇文章 0 订阅

This is the easy version of the problem. The difference is the constraints on nn, mm and tt. You can make hacks only if all versions of the problem are solved.

Alice and Bob are given the numbers nn, mm and kk, and play a game as follows:

The game has a score that Alice tries to maximize, and Bob tries to minimize. The score is initially 00. The game consists of nn turns. Each turn, Alice picks a real number from 00 to kk (inclusive) which Bob either adds to or subtracts from the score of the game. But throughout the game, Bob has to choose to add at least mm out of the nn turns.

Bob gets to know which number Alice picked before deciding whether to add or subtract the number from the score, and Alice gets to know whether Bob added or subtracted the number for the previous turn before picking the number for the current turn (except on the first turn since there was no previous turn).

If Alice and Bob play optimally, what will the final score of the game be?

Input

The first line of the input contains a single integer tt (1≤t≤10001≤t≤1000) — the number of test cases. The description of test cases follows.

Each test case consists of a single line containing the three integers, nn, mm, and kk (1≤m≤n≤2000,0≤k<109+71≤m≤n≤2000,0≤k<109+7) — the number of turns, how many of those turns Bob has to add, and the biggest number Alice can choose, respectively.

It is guaranteed that the sum of nn over all test cases does not exceed 20002000.

Output

For each test case output a single integer number — the score of the optimal game modulo 109+7109+7.

Formally, let M=109+7M=109+7. It can be shown that the answer can be expressed as an irreducible fraction pqpq, where pp and qq are integers and q≢0(modM)q≢0(modM). Output the integer equal to p⋅q−1modMp⋅q−1modM. In other words, output such an integer xx that 0≤x<M0≤x<M and x⋅q≡p(modM)x⋅q≡p(modM).

Example

input

Copy

7
3 3 2
2 1 10
6 3 10
6 4 10
100 1 1
4 4 0
69 4 20

output

Copy

6
5
375000012
500000026
958557139
0
49735962

Note

In the first test case, the entire game has 33 turns, and since m=3m=3, Bob has to add in each of them. Therefore Alice should pick the biggest number she can, which is k=2k=2, every turn.

In the third test case, Alice has a strategy to guarantee a score of 758≡375000012(mod109+7)758≡375000012(mod109+7).

In the fourth test case, Alice has a strategy to guarantee a score of 452≡500000026(mod109+7)452≡500000026(mod109+7)

思路:又是没有给我们概率p,(!每种情况都相同),我们无法枚举每个数字都上去判断一遍,会超时。我们定义dp[i][j], i 表示进行了i回合,j 表示选了几个加法。那么假设我们选了一个数x,那么选上这个数就是:dp[i-1][j-1]+x ;没选这个数就是:dp[i-1][j]-x。这里可以知道我们的x这个数无法枚举,但x这个数是依次递增的,x不能是固定值(也就不是常数),那么x可以看作变量,而dp的值是确定的,可以看作是常数。Bob想要最小:min( dp[i-1][j-1]+x , dp[i-1][j]-x ),而Alice想要最大的,那么就要让最小值取最大(下面的图更好理解):

那么这个y(即dp)的值的大小 就是黑色两个端点的值相加,也就是:dp[i][j]=(dp[i-1][j-1] + dp[i-1][j] )/2。只需要在求一下2的逆元即可。(还有一个边界就是n=m时,那就只能选最大了,选n个,即dp[i][i]=n*k了,dp记得先处理边界

(ps:简单的期望不需要dp,较难的期望需要先求出dp,再计算期望。需要dp时,但是会有一个非常大的循环,这就需要将这个循环设成变量,带入dp之中来求关系

(没给概率p时,就先求概率或一个数的期望,不好求时,直接dp。n=2000,范围不大的,能直接去想dp,就看n的范围,先看范围!

(有逆元:说明分母是离我们比较近的,例如:2^n , 2)

完整代码:

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;
//#define int long long
#define fir first
#define sec second
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)x.size()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define repd(i, l, r) for (int i = l; i >= r; --i)
#define pb push_back

//#define mint modint<(int)1e9 + 7>

#define defop(type, op) \
    inline friend type operator op (type u, const type& v) { return u op ##= v; } \
    type& operator op##=(const type& o)
template<int mod>
struct modint {
    int x;
    // note that there is no correction, simply for speed
    modint(int xx = 0): x(xx) {}
    modint(ll xx): x(int(xx % mod)) {}
    defop(modint, +) {
        if ((x += o.x) >= mod) x -= mod;
        return *this;
    }
    defop(modint, -) {
        if ((x -= o.x) < 0) x += mod;
        return *this;
    }
    defop(modint, * ) { return *this = modint(1ll * x * o.x); }
    modint pow(ll exp) const {
        modint ans = 1, base = *this;
        for (; exp > 0; exp >>= 1, base *= base)
            if (exp & 1) ans *= base;
        return ans;
    }
    defop(modint, /) { return *this *= o.pow(mod - 2); }
};
//using mint = modint<(int)1e9 + 7>;
typedef  modint<(int)1e9 + 7> mint;

const int mod=1e9+7;
ll dp[2020][2020];

ll qmi(ll a,ll k)
{
    ll res=1;
    while(k)
    {
        if(k&1)res=res*a%mod;
        k>>=1;
        a=a*a%mod;
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin>>t;
    while(t--)
    {
        ll n,m,k;
        cin>>n>>m>>k;
        rep(i,1,n)
        {
            //dp[i][0]=0;
            dp[i][i]=i*k%mod;
        }
        rep(i,1,n)
        {
            rep(j,1,m)
            {
                if(i!=j)
                {
                    dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%mod*qmi(2,mod-2)%mod; //说明分母离我们比较近
                }
            }
        }
        cout<<dp[n][m]<<endl;
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值