标签:
题意:你邀请n个好友聚会,好友之间互相认识的要喝酒,你和每个好友也要喝酒,问要准备多少杯酒。
题解:答案为$$ans=2*n+bit{mat}$$其中$bit{mat}$表示关系矩阵中1的个数。 ```c++
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;
}
题意:给一排树的高度,分别为$h[1],h[2],{...},h[n]$,JB大哥站在最左边,每次给个高度$q[i]$,问最近的高度为$q[i]$的树编号是多少。
题解:考虑不同高度的树,对某个高度的树,维护一颗平衡二叉树,同时所有高度也用一颗平衡二叉树维护,于是查找复杂度可为$log(m)+log(n)$,其中$m,n$分别表示不同高度的个数和该高度下树的棵数。
```c++
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; } ```
题意: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++
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; } ```
标签:
原文地址:http://blog.csdn.net/bit_line/article/details/46238409