에디 워커
질문의 의미하는
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 파티션 문제
질문의 의미
최대 총 경쟁력있는 가치를 추구, 두 팀으로 나누어 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 두 번째로 큰 직사각형
질문의 의미는
엄격한 번째 큰 사각형을 요구하지 않습니다.
생각
서스펜션 와이어 히타 단조로운 스택.
매달려 라인 방법 알아
종이 : 이야기하면 직사각형의 서브 극대화 아이디어의 가장 큰 문제를 해결하기 위해
#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;
}