码迷,mamicode.com
首页 > 其他好文 > 详细

【套题】Bestcoder#42

时间:2015-05-29 23:21:54      阅读:352      评论:0      收藏:0      [点我收藏+]

标签:

第一题  Shaking hands

  • 题意:你邀请n个好友聚会,好友之间互相认识的要喝酒,你和每个好友也要喝酒,问要准备多少杯酒。

  • 题解:答案为$$ans=2*n+bit{mat}$$其中$bit{mat}$表示关系矩阵中1的个数。 ```c++

include <bits/stdc++.h>

int main() { int n, a;

while (~scanf(" %d", &n)) {
    int sum = n << 1;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf(" %d", &a);
            sum += a;
        }
    }
    printf("%d\n", sum);
}
return 0;

}

```

第二题  Gunner II

  • 题意:给一排树的高度,分别为$h[1],h[2],{...},h[n]$,JB大哥站在最左边,每次给个高度$q[i]$,问最近的高度为$q[i]$的树编号是多少。

  • 题解:考虑不同高度的树,对某个高度的树,维护一颗平衡二叉树,同时所有高度也用一颗平衡二叉树维护,于是查找复杂度可为$log(m)+log(n)$,其中$m,n$分别表示不同高度的个数和该高度下树的棵数。

```c++

include <bits/stdc++.h>

using namespace std;

int main() { int n, m; map<int, set > S; map<int, set >::iterator it; set toInsert; while (~scanf(" %d %d", &n, &m)) { S.clear(); int a; for (int i = 1; i <= n; ++i) { scanf(" %d", &a); if ((it = S.find(a)) != S.end()) { (it->second).insert(i); //printf("push height %d\n", a); } else { toInsert.clear(); toInsert.insert(i); S.insert(make_pair(a, toInsert)); //printf("new to height %d\n", a); } } for (int i = 1; i <= m; ++i) { scanf(" %d", &a); if ((it = S.find(a)) == S.end()) { puts("-1"); } else { printf("%d\n", *(it->second).begin()); (it->second).erase((it->second).begin()); if ((it->second).empty()) { S.erase(it); } } } } return 0; } ```

第三题  Happy birthday

  • 题意:JB大哥吃蛋糕,从左上角一直吃到右下角,但是肚子有个容量$K$,问最多可以吃多少。

  • 题解:简单dp,定义状态$dp[i][j][k]$表示在位置$(i,j)$能否吃到$k$的蛋糕。转移:$$dp[i][j][k]=dp[i-1][j][k]\lor dp[i][j-1][k]\lor (k>=cake[i][j] \land (dp[i][j-1][k-cake[i][j]]\lor dp[i-1][j][k-cake[i][j]])$$ 初始化$dp[i][j][0]=true$ ```c++

include <bits/stdc++.h>

using namespace std;

const int MAX = 107; int cake[MAX][MAX]; bool dp[MAX][MAX][MAX];

int main() { int n, m, K; while (~scanf(" %d %d %d", &n, &m, &K)) { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { scanf(" %d", &cake[i][j]); } } memset(dp, false, sizeof(dp)); for (int i = 0; i <= n; ++i) { for (int j = 0; j <= m; ++j) { dp[i][j][0] = true; } } //dp[i][j][k]: if he can eat k(g) at position(i, j) for (int i = 0; i <= n; ++i) { for (int j = 0; j <= m; ++j) { for (int k = 0; k <= K; ++k) { if (dp[i][j][k]) { dp[i][j + 1][k] = dp[i + 1][j][k] = true; if (k + cake[i][j + 1] <= K) { dp[i][j + 1][k + cake[i][j + 1]] = true; } if (k + cake[i + 1][j] <= K) { dp[i + 1][j][k + cake[i + 1][j]] = true; } } } } } for (int i = K; i >= 0; --i) { if (dp[n][m][i]) { printf("%d\n", i); break; } } } return 0; } ```

【套题】Bestcoder#42

标签:

原文地址:http://blog.csdn.net/bit_line/article/details/46238409

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!