生活随笔
收集整理的這篇文章主要介紹了
Optimal Strategy 组合数,dp,博弈论(济南)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意 :
- 有n個(gè)數(shù),E和M輪流取,使各自取到的值之和最大,最優(yōu)策略,問取數(shù)的過程有多少種
思路 :
- 分析樣例可知不能貪心的去做,不一定每回合玩家都拿最大的,而是與每回合剩余的數(shù)中最大的有關(guān),那么就是與每個(gè)值的個(gè)數(shù)有關(guān),又進(jìn)一步想到是與每個(gè)值的個(gè)數(shù)的奇偶性有關(guān)
值為i的元素,那么所有小于i的元素都不必再按兩兩配對(duì)考慮,因?yàn)樗鼈內(nèi)魏我粋€(gè)都不是此時(shí)序列中的最大值,可以任意順序取走
#include <iostream>
#define endl '\n'using namespace std
;typedef long long ll
;const int N
= 1e6 + 50, M
= 1e6 + 100;
const ll mod
= 998244353;ll n
;
ll f
[N
];
ll cnt
[N
], sum
[N
];ll fac
[M
], inv
[M
];int power(int a
, int b
)
{int ret
;if (b
== 0) return 1;ret
= power(a
, b
/ 2);ret
= 1ll * ret
* ret
% mod
;if (b
% 2) ret
= 1ll * ret
* a
% mod
;return ret
;
}void init()
{fac
[0] = 1, inv
[0] = 1;for (int i
= 1; i
<= 1000000; i
++ ){fac
[i
] = 1ll * fac
[i
- 1] * i
% mod
;inv
[i
] = power(fac
[i
], mod
- 2);}
}int C(int n
, int m
)
{if (n
< m
) return 0;if (n
< 0 || m
< 0) return 0;return 1ll * fac
[n
] * inv
[m
] % mod
* inv
[n
- m
] % mod
;
}void solve()
{cin
>> n
;for (int i
= 1, x
; i
<= n
; i
++ ) cin
>> x
, cnt
[x
] ++ ;for (int i
= 1; i
<= n
; i
++ ) sum
[i
] = sum
[i
- 1] + cnt
[i
];bool flag
= false;for (int i
= 1; i
<= n
; i
++ ){if (!cnt
[i
]){f
[i
] = f
[i
- 1];continue;}if (!flag
){flag
= true;f
[i
] = 1;for (int j
= 2; j
<= cnt
[i
]; j
++ ) f
[i
] = (f
[i
] * j
) % mod
;continue;}f
[i
] = f
[i
- 1] * C(sum
[i
- 1] + cnt
[i
] / 2, sum
[i
- 1]) % mod
;for (int j
= 2; j
<= cnt
[i
]; j
++ ) f
[i
] = (f
[i
] * j
) % mod
;}cout
<< f
[n
] << endl
;
}int main()
{ios
::sync_with_stdio(false); cin
.tie(0); cout
.tie(0);int _
= 1;
while (_
--){init();solve();}return 0;
}
總結(jié)
以上是生活随笔為你收集整理的Optimal Strategy 组合数,dp,博弈论(济南)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。