/* **********************************************
File Name: test.cpp
Auther: [email protected]
Created Time: 2015/11/1 12:34:01
*********************************************** */
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0xfffffff;
const int MAX = 100007;
int a[MAX];
int dp[MAX]; //dp[i] length is i min
int inc(int n) {
fill(dp, dp + n + 1, INF);
dp[0] = -INF;
for (int i = 1; i <= n; ++i) {
int sz = upper_bound(dp, dp + i, a[i]) - dp;
//printf("get %d\n", sz);
dp[sz] = a[i];
}
for (int i = n; i >= 1; --i) {
if (dp[i] < INF) {
return i;
}
}
return 0;
}
int dec(int n) {
reverse(a + 1, a + n + 1);
return inc(n);
}
int main() {
int T, n;
scanf(" %d", &T);
while (T--) {
scanf(" %d", &n);
for (int i = 1; i <= n; ++i) {
scanf(" %d", a + i);
}
puts((inc(n) >= n - 1 || dec(n) >= n - 1) ? "YES" : "NO");
}
return 0;
}
/* **********************************************
File Name: 5533.cpp
Auther: [email protected]
Created Time: 2015年11月02日 星期一 20时33分46秒
*********************************************** */
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const double INF = FLT_MAX;
const double EPS = 1e-8;
const double PI = acos(-1.0);
const int MAX = 107;
inline int sign(double x) {
if (fabs(x) < EPS) return 0;
if (x > 0.0) return 1;
return -1;
}
struct Point {
double x, y;
Point() {}
Point(double _x, double _y): x(_x), y(_y) {}
Point operator-(const Point& ne)const {
return Point(x - ne.x, y - ne.y);
}
Point operator+(const Point& b)const {
return Point(x + b.x, y + b.y);
}
Point operator*(const double t)const {
return Point(t * x, t * y);
}
Point operator/(const double t)const {
if (sign(t) == 0) return Point(INF, INF);
return Point(x / t, y / t);
}
double operator^(const Point& b)const {
return (x - b.x) * (x - b.x) + (y - b.y) * (y - b.y);
}
} ping[MAX];
struct Polygon {
Point p[MAX];
int n;
} ans;
inline double xmult(Point o, Point a, Point b) {
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
bool cmp(const Point& a, const Point& b) {
return a.x < b.x || (sign(a.x - b.x) == 0 && a.y < b.y);
}
void convex_hull(Point p[MAX], int n, Polygon& res) {
res.n = 0;
sort(p, p + n, cmp);
int i, j, top;
for (i = 0, top = 0; i < n; ++i) {
while (top > 1 && xmult(res.p[top - 2], res.p[top - 1], p[i]) < EPS) {
--top;
}
res.p[top++] = p[i];
}
j = top;
for (i = n - 2; i >= 0; --i) {
while (top > j && xmult(res.p[top - 2], res.p[top - 1], p[i]) < EPS) {
--top;
}
res.p[top++] = p[i];
}
res.n = top - 1;
}
int main() {
int T, n;
scanf(" %d", &T);
while (T--) {
scanf(" %d", &n);
for (int i = 0; i < n; ++i) {
scanf(" %lf %lf", &ping[i].x, &ping[i].y);
}
convex_hull(ping, n, ans);
if (n < 3 || ans.n != n) {
puts("NO");
continue;
}
double leng = ans.p[0] ^ ans.p[n - 1];
bool flag = true;
for (int i = 0; i < n - 1; ++i) {
if (sign((ans.p[i] ^ ans.p[i + 1]) - leng)) {
flag = false;
break;
}
}
puts(flag ? "YES" : "NO");
}
return 0;
}
题解: n 个点, n−1 条边,共有 2∗n−2 个度需要分配。可以证明,首先对每个顶点赋一个度,将剩余的 n−2 个度任意分配给剩下的顶点,均可以得到一棵树。我们可以简单地反证一下~
题解续:做完上述分析,我们就可以先考虑一个简化版本了。容量为 n−2 的背包,有 n−1 件物品,分别为大小为 i ,价值为 fi ,有无限多个,问装满背包最大获得价值为多少。
/* **********************************************
File Name: 5534.cpp
Auther: [email protected]
Created Time: 2015/11/3 22:22:19
*********************************************** */
#include
using namespace std;
typedef pair<int, int> P;
const int INF = 0xfffffff;
const int MAX = 2018;
vector bag;
int dp[MAX];
int f[MAX];
int m;
void push(int weight, int value) {
for (int i = 1; i * weight <= m; i <<= 1) {
bag.push_back(P(weight * i, value * i));
//printf("push (%d, %d)\n", weight * i, value * i);
}
}
int main() {
int T, n;
scanf(" %d", &T);
while (T--) {
bag.clear();
scanf(" %d", &n);
m = n - 2;
for (int i = 1; i < n; ++i) {
scanf(" %d", f + i);
}
int ans = n * f[1];
for (int i = 2; i < n; ++i) {
push(i - 1, f[i] - f[1]);
}
sort(bag.begin(), bag.end());
unique(bag.begin(), bag.end());
fill(dp, dp + m + 1, -INF);
dp[0] = 0;
for (int i = 0; i < bag.size(); ++i) {
for (int j = m; j >= bag[i].first; --j) {
if (dp[j - bag[i].first] + bag[i].second > dp[j]) {
dp[j] = dp[j - bag[i].first] + bag[i].second;
}
}
}
printf("%d\n", dp[m] + ans);
}
return 0;
}
/* **********************************************
File Name: 5536.cpp
Auther: [email protected]
Created Time: 2015/11/3 21:38:44
*********************************************** */
#include
using namespace std;
typedef long long ll;
const ll MAX = 1LL << 32;
const int CNT = 1024;
int a[CNT];
struct Node {
Node* son[2];
int cnt;
Node(int _x = 0): cnt(_x) {
son[0] = son[1] = NULL;
}
};
void insert(Node* T, int x) {
for (ll ck = MAX; ck > 0; ck >>= 1) {
int idx = (x & ck) > 0 ? 1 : 0;
if (T->son[idx] == NULL) {
T->son[idx] = new Node();
}
++(T->son[idx]->cnt);
T = T->son[idx];
}
}
void remove(Node* T, int x) {
for (ll ck = MAX; ck > 0; ck >>= 1) {
int idx = (x & ck) > 0 ? 1 : 0;
--(T->son[idx]->cnt);
T = T->son[idx];
}
}
void clear(Node* T) {
if (T == NULL) {
return;
}
for (int i = 0; i < 2; ++i) {
clear(T->son[i]);
}
delete T;
}
int gao(Node* T, int x) {
int res = 0;
for (ll ck = MAX; ck > 0; ck >>= 1) {
int idx = (x & ck) > 0 ? 1 : 0;
res <<= 1;
if (T->son[idx ^ 1] != NULL && T->son[idx ^ 1]->cnt > 0) {
T = T->son[idx ^ 1];
res |= idx ^ 1;
} else {
T = T->son[idx];
res |= idx;
}
}
return res;
}
int main() {
int T, n;
scanf(" %d", &T);
while (T--) {
scanf(" %d", &n);
Node* T = new Node();
for (int i = 0; i < n; ++i) {
scanf(" %d", a + i);
insert(T, a[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
remove(T, a[i]);
for (int j = 0; j < n; ++j) {
if (j == i) continue;
remove(T, a[j]);
int res = gao(T, a[i] + a[j]);
//printf("remove %d, %d, get %d\n", a[i], a[j], res);
ans = max(ans, res ^ (a[i] + a[j]));
//ans = max(ans, gao(T, a[i] + a[j]));
insert(T, a[j]);
}
insert(T, a[i]);
}
clear(T);
printf("%d\n", ans);
}
return 0;
}
/* **********************************************
File Name: 5538.cpp
Auther: [email protected]
Created Time: 2015年11月02日 星期一 20时31分00秒
*********************************************** */
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int MAX = 64;
int a[MAX][MAX];
int main() {
int T, n, m;
scanf(" %d", &T);
while (T--) {
scanf(" %d %d", &n, &m);
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf(" %d", &a[i][j]);
}
}
int sum = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (a[i][j] > 0) ++sum;
sum += max(0, a[i][j] - a[i - 1][j]);
sum += max(0, a[i][j] - a[i][j - 1]);
sum += max(0, a[i][j] - a[i + 1][j]);
sum += max(0, a[i][j] - a[i][j + 1]);
}
}
printf("%d\n", sum);
}
return 0;
}