Aエディウォーカー
質問の意味が
0を持っている...、N-1、円の中にn個の点の合計は、開始点は0、NおよびMは、それはNステップの確率ですべてのポイントを通過し、最終的にポイントMで停止し、このような状況を見つけるだろうと述べました。
アイデアは、
確率は1 /(N-1)で、おそらく推測、カスタム計算の円の大きさ、各停止点での回数、法律を見つけるためにテーブルを打ちます。
テーブルコードを再生します:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 7;
int vis[maxn], ans[maxn];
int main()
{
int n, pos, cnt;
scanf("%d", &n);
srand((time(0)));
for(int i = 1; i <= 100000; i++)
{
memset(vis, 0, sizeof(vis));
vis[0] = 1;
pos = 0;
cnt = 1;
while(cnt < n)
{
int moving = rand() % 2 ? 1 : -1;
pos = (pos + moving + n) % n;
if(!vis[pos])
{
vis[pos] = 1;
cnt++;
}
if(cnt == n)
{
ans[pos]++;
}
}
}
for(int i = 0;i < n; i++)
printf("%d ", ans[i]);
printf("\n");
return 0;
}
ACコード:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 7;
ll qpow(ll a, ll b)
{
ll ans = 1;
a = a % mod;
while (b) {
if(b&1) ans = ans * a% mod;
a = a * a % mod;
b = b >> 1;
}
return ans;
}
int main()
{
int t;
cin >> t;
ll ans = 1;
while (t--) {
ll n, m;
cin >> n >> m;
if(n == 1 && m == 0) {
printf("%lld\n", ans);
continue;
}
else if(m == 0) {
ans = 0;
printf("%lld\n", ans);
continue;
}
printf("%lld\n", ans = ans * qpow(n - 1, mod - 2) % mod);
}
return 0;
}
Fパーティションの問題
質問の意味
最大合計競争力の値を求めて、2つのチームに分かれ2N個人を、。
アイデア
暴力パケットが、タイムアウトになり、それはまだ、前処理を必要とします。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30 +7;
typedef long long ll;
int m, w[maxn][maxn];
ll sum[maxn][maxn], ans = 0;
int A;
void dfs(int x, int xx, ll v)//x表示选到第x个,xx表示选了xx个
{
if(xx == m) {
for (int i = 1; i < x; i++) {
if(A &(1<<i))
v += sum[i][2 * m] - sum[i][x - 1];
}
if(v > ans) ans = v;
return;
}
if(x - xx - 1 == m) {
for (int i = 1; i < x; i++) {
if(!(A&(1<<i)))
v += sum[i][2 * m] - sum[i][x - 1];
}
if(v > ans)
ans = v;
return;
}
//不选
ll t = 0;
for (int i = 1; i < x; i++) {
if(A&(1<<i)) t += w[i][x];
}
dfs(x + 1, xx, v + t);
//选
t = 0;
for (int i = 1; i < x; i++) {
if(!(A&(1<<i)))
t += w[i][x];
}
A|= 1<<x;
dfs(x + 1, xx + 1, v + t);
A &= ~(1<<x);
}
int main()
{
scanf("%d", &m);
for (int i = 1; i <= 2 * m; i++) {
for (int j = 1; j <= 2 * m; j++) {
scanf("%d", &w[i][j]);
}
}
for (int i = 1; i <= 2 * m; i++) {
for (int j = 1; j <= 2 * m; j++) {
sum[i][j] = sum[i][j - 1] + w[i][j];//预处理
}
}
A |= 1<<1;
dfs(2, 1, 0LL);
cout << ans << endl;
}
H第2の大四角形
質問の意味は
、厳密な第2の大矩形を要求されていません。
考え
サスペンションワイヤファヒータ単調スタック。
ライン方式のぶら下げを学ぶ
:紙長方形のサブ最大限アイデアの最大の問題を解決するために話すと
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 7;
typedef long long ll;//g是原图 g[i][j] = 1表示所求的最大子矩形的组成元素
int g[maxn][maxn], h[maxn][maxn];
priority_queue<int, vector<int>, greater<int> > q;
void add(int x)
{
q.push(x);
while (q.size() > 2) q.pop();
}
int st[maxn];
int width[maxn];
int main()
{
int n, m;
int ans = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%1d", &g[i][j]);
h[i][j] = g[i][j] ? h[i - 1][j] + 1: 0;
}
h[i][m + 1] = 0;
}
q.push(0); q.push(0);
for (int i = 1; i <= n; i++) {
int top = 0;
for (int j = 1; j <= m + 1; j++) {
if(st[top] < h[i][j]) {
st[++top] = h[i][j];
width[top] = 1;
}
else {
int w = 0;
while (st[top] > h[i][j]) {
w += width[top];
add(st[top] * w);
add(st[top] * (w - 1));
add((st[top] - 1) * w);
top--;
}
st[++top] = h[i][j];
width[top] = w + 1;
}
}
}
printf("%d\n", q.top());
return 0;
}