CF339
有1...10k的砝码,在天枰上,左右轮流放置砝码,要求之后左右轮流比另一侧重量要大,要求相邻两次砝码不能相同。
解题报告给出(i,j,k)表示balance,j表示最后一次的砝码重量,k表示第几步,然后表示从点(0,0,0)->(x,y,m)的图论问题,跟动态规划是等价的,复杂度是O(w^3*m)。
我给出了一个比上述算法更优的一个算法,做法是用dp[i][j]表示第i步balance达到j时的所有可能的砝码情况的二进制mask,复杂度是O(w^2*m),但要求w<32。
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std; int dp[][];
char w[]; int main() {
int m;
scanf("%s%d", w, &m); memset(dp, , sizeof(dp));
dp[][] = ; for (int i = ; i <= m; i++) {
for (int j = ; j <= ; j++) {
if (dp[i - ][j] > ) {
for (int k = ; k <= ; k++) if (w[k - ] == '') {
if (dp[i - ][j] ^ ( << k)) {
if (j >= && j - k < ) {
dp[i][j - k] |= ( << k);
} else if (j < && j + k > ) {
dp[i][j + k] |= ( << k);
}
}
}
}
}
} int ans_j = -;
for (int j = ; j <= ; j++) if (dp[m][j] > )
ans_j = j; if (ans_j == -) {
printf("NO\n");
} else {
printf("YES\n");
int i = m;
vector<int> ans;
int last = ;
while (i > ) {
for (int j = ; j <= ; j++) {
if (dp[i][ans_j] & ( << j)) {
if (j == last) continue; ans.push_back(j); if (ans_j >= ) ans_j -= j;
else ans_j += j; last = j; break;
}
}
i--;
}
for (i = ans.size() - ; i >= ; i--) {
printf("%d ", ans[i]);
}
printf("\n");
}
}
很裸的一个线段树了。
#include <cstdio>
#include <iostream>
using namespace std; const int MAXN = << ; int num[MAXN]; class SegNode {
public:
int L, R;
int level, sum;
} node[MAXN * ]; class SegTree {
public:
void build(int r, int L, int R) {
node[r].L = L;
node[r].R = R; if (L == R) {
// leaf
node[r].level = ;
node[r].sum = num[L];
} else {
// non leaf
int M = (L + R) / ;
build( * r, L, M);
build( * r + , M + , R);
node[r].level = node[ * r].level + ;
if (node[r].level & ) {
node[r].sum = node[ * r].sum | node[ * r + ].sum;
} else {
node[r].sum = node[ * r].sum ^ node[ * r + ].sum;
}
}
}
void update(int r, int p, int b) {
if (node[r].L == node[r].R) {
node[r].sum = b;
} else {
if (p <= node[ * r].R) {
// left
update( * r, p, b);
} else if (p >= node[ * r + ].L) {
// right
update( * r + , p, b);
}
if (node[r].level & ) {
node[r].sum = node[ * r].sum | node[ * r + ].sum;
} else {
node[r].sum = node[ * r].sum ^ node[ * r + ].sum;
}
}
}
} tree; int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= ( << n); i++) {
scanf("%d", &num[i]);
}
tree.build(, , << n);
for (int i = ; i < m; i++) {
int p, b;
scanf("%d%d", &p, &b);
tree.update(, p, b);
printf("%d\n", node[].sum);
}
}
CF339的更多相关文章
随机推荐
- UML静态类图
0,主要分为类.接口.协作.关系,这四种元素.作用:a,显示类.接口以及他们之间的静态结构和关系:b,用于描述系统的结构化设计. 1,类 CStudent +m_strName : string +S ...
- Windows内存原理与内存管理
WIndows为每个进程分配了4GB的虚拟地址空间,让每个进程都认为自己拥有4GB的内存空间,4GB怎么来的? 32位 CPU可以取地址的空间为2的32次方,就是4GB(正如16位CPU有20根寻址线 ...
- Android版的疯狂猜图游戏源码完整版分享
这个游戏源码是在安装教程网那么分享过来的,Android版的疯狂猜图游戏源码完整版分享,也是本人之前很早以前发的一款游戏源码的,大家如果想了解一下,可以看看吧,不说多了,上一个图先吧. > ...
- 解决firefox经常出现Adobe Flash 插件已崩溃
官方解决方法: 方案1:更新 Flash 方案2: 降级到 Flash 10.3 方案3:禁用 Flash 沙箱特性 最近很长一段时间用firefox浏览多个含大量图片和flash视频的网页经常会卡顿 ...
- 【原】web页面登陆验证
using Itcast.Mall.Model; using System; using System.Collections.Generic; using System.Linq; using Sy ...
- C#使用Zxing2.0生成二维码 带简单中心LOGO
参考:http://www.open-open.com/lib/view/open1379214678162.html 代码:http://files.cnblogs.com/halo/%E4%BA% ...
- java日志框架与日志系统
日志框架:提供日志调用的接口,实际的日志输出委托给日志系统实现. JCL(Jakarta Commons Logging):比较流行的日志框架,很多框架都依赖JCL,例如Spring等. SLF4j: ...
- Nat网络地址转换
Nat中的术语 -------------------------------------------------------------------------------------------- ...
- 第一章 基本的SQL语句 (SQL基础)
1. 查询数据库系统时间,常以服务器默认的格式进行显示(根据数据库的字符集而定): 注意:dual 为数据库中的虚表,隶属于管理员 sys 用户,但所有的用户都可以访问:无实际意义,仅充当select ...
- C#...何时需要重写ToString()方法?
一般类型,都是继承自System.Object类,默认情况下,object类的ToString方法会返回当前类的类型的字符串表达形式.但也有例外!! DateTime,它就重写ToString方法,D ...