[ACM] POJ1185解题报告 状态压缩DP
by Viaxl on Aug.23, 2010
思路和网上的都差不多, 我另外开了程序算出每一行可能的情况直接copy进 stack[] 中..耍流氓.. 看起来直观点
引用一下大牛BYVoid的思路, 不自己写了
较难看出的动态规划问题。注意到数据范围N≤100;M≤10,发现每行的宽度都不大,所以可以考虑把一行看成一个状态,表示该行的布置方案。每行的布置方案可以预先处理出,由数学知识可以算出,每行最多的布置方案数也不过60个而已。
状态设定
F[i,a,b]为前i行,第i行的方案为A[a],第i-1行的方案为A[b]的最大炮兵数。
状态转移方程
- F[i,a,b]=Max{ F[i-1,b,c] + P[a] }
其中c为i-2行的布置方案,a,b,c应保证互不冲突,即放置方案中炮兵都在平地上,且不会互相攻击到。
目标结果
- Ans=Max{F[N,a,b]}
中间进行过一次错误的优化, 认为如果, 比如
画个图..
- HHPH
PPPP
PPPP
HHPH (红色代表有炮)
1001比1101少了一个1, 那么1101得出的结果至少不会比1001差, 可以剪掉1001. 比如上图的第三行, 没有炮的情况就可以省去,.我当时的想法是如果省掉第三行的炮, 放在第四行唯一的P上(其他情况也是相似), 第四行以下面临的情况就会比之前更加严峻, 从而不会得出更好的结果, 顶多一样.
但是我并没有考虑第三行能对第一行也产生影响 (造成这个错误的原因是状态压缩DP只记录近两行. 虽然没有明面上写, 但是情况已经记录在得分中了). 第三行的P不放炮, 则第一行和第四行都能放, 结果就更好了.
遗留问题, 如何才能在类的定义中实现二维数组的动态分配?
我写成这样
public:
int *(a[60]);
State (int m=0) {
M=m;
for(int i=0;i<stackN;i++) {
a[i]=new int[stackN];
memset(a[i],0xff,sizeof(int)*stackN);
}
}
能够compile, 在另开的程序里也没有问题, 但是在题目中答案就不一样, 我跟踪了, 在 s[i].dp(s[i-1]) 的过程中 s[i-1].a[][] 会莫名发生改变, 实际上又没有对它进行任何操作. 值得一提的是release和debug得出的答案不一样, 根据经验应该是内存的什么问题.. 也有可能是类里动态分配内存就不对头, 因为在类中定义变量不能用new.. 开学去问问看
Code: (其实是我第一次用类.. 这个问题有点绕, 于是尝试封装=D )
尚邮玩儿蛋去吧! --为什么中国用不了真正的Pushmail
by Viaxl on Aug.19, 2010
尚邮, 139邮箱什么的全是玩噱头的松货.
现在流行的所谓的pushmail有两种
1. 保持gprs连接的, 声称几乎没流量但是连接还在阿, 耗电是平时两倍阿. google到某篇文章竟然说blackberry是这种的, 气的我查了半天写了这篇文章.
2.发短信通知的, 比如移动139, 就是个笑话, 慢不说, 还没加密, 还装客户端, 擦, 看移动官网做的那样谁敢用你的软件.
知道blackberry为什么牛逼么, 靠的就是真正的pushmail, push的就是mail, 别的什么都没有!
Cort X6换EMG 81 85拾音器
by Viaxl on Aug.11, 2010
去年换的81.. 今年加个85, 85声音好美, 像5000元的琴…
[ACM] POJ3295解题报告
by Viaxl on Aug.03, 2010
这是所谓的二叉树么.. 算法很简单, 只是因为第一次用这种结构体封装, 还是试了很多次才摸索出来的.. 很好用诶! 记一下
细节.. 地址和变量不要搞混了.. fw?fw->v():false 我写成了fw->v()? 错了好久
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Orz {
Orz *fw,*fx;
bool (*f)(bool w,bool x);
bool v() {
return (*f)(fw?fw->v():false,fx?fx->v():false);
};
bool p[5];
char sb[]={'K','A','C','E','N','p','q','r','s','t'};
char input[201];
int count;
bool fK(bool w,bool x) { return w&x; }
bool fA(bool w,bool x) { return w|x; }
bool fC(bool w,bool x) { return !(w&&!x); }
bool fE(bool w,bool x) { return !(w^x); }
bool fN(bool w,bool x) { return !w; }
bool fp(bool w,bool x) { return p[0]; }
bool fq(bool w,bool x) { return p[1]; }
bool fr(bool w,bool x) { return p[2]; }
bool fs(bool w,bool x) { return p[3]; }
bool ft(bool w,bool x) { return p[4]; }
bool (*f[])(bool w,bool x)={fK,fA,fC,fE,fN,fp,fq,fr,fs,ft};
Orz *proc() {
char a=input[count++];
Orz *node=(Orz *)malloc(sizeof(Orz));
node->fw=node->fx=NULL;
int type;
for(type=0;sb[type]!=a;type++);
node->f=f[type];
if(type<=4)
node->fw=proc();
if(type<4)
node->fx=proc();
return node;
}
int pow2(int n) {
int r=1;
for(int i=0;i<n;i++)
r*=2;
return r;
}
int main() {
while(1) {
gets(input);
if(input[0]=='0')
break;
count=0;
Orz *bigBang=proc();
short tester;
for(tester=0x0000;tester<=0x001f;tester++) {
for(int i=0;i<5;i++)
p[i]=tester/pow2(i)%2;
if(bigBang->v()!=true)
break;
}
if(tester==0x0020)
printf("tautology\n");
else
printf("not\n");
}
return 0;
}
怎样删掉恼人的IE
by Viaxl on Jul.23, 2010
傻逼才用IE呢. —-题记
(转载请注明 http://viaxl.com)
流氓软件经常在后台打开iexplore.exe进程干一些恶心的勾当, 比如给网站刷流量, 点广告, 或者像我的时不时就放音乐.. 每次都要结束进程很烦人, 对于懒得杀毒的同学来说, 删了ie是暴力且效率的做法..
反正也不用它, (除了网银,所以备份一下), 详情:
http://www.firefox.com
http://chrome.google.com
Step1. 进C:\Program Files\Internet Explorer目录(不管你是哪个windows版本都一样)
Step2. 把iexplore.exe改名, 但是这时即使有管理员权限也没办法, 因为没有”可信任安装程序”的权限? 什么毛? 我是root啊. windows真是没法说..
Step3. 所以我们需要用这个小工具..
http://www.sevenforums.com/tutorials/1911-take-ownership-shortcut.html?ltr=T
导入注册表后, 返回上一级Program Files目录, 右键点Internet Explorer文件夹, 点Take Ownership选项, 好了现在可以随心所欲的把iexplore.exe改名了, 奈斯.
(直接右键属性是没法得到权限的..what the hell 我是root啊.. 但是改注册表却可以? 诶哟为, 好歹我还是root. windows没法说..)
这样你想删什么删什么可以把windows目录删掉(没有在使用中的文件)..
比鼠标垫更要紧--如何去除鼠标加速 (适用于vista/win7!)
by Viaxl on Jun.29, 2010
Xp下去除加速度很简单, 注册表里改一下就行了. 但是vista/win7好像一直没什么好办法(我是win7系统).
控制面板里去掉, 游戏里还是有. 有说加 -noforcemparms什么参数的也是人云亦云, 我试了基本都没什么用. 经过艰苦的Google, 终于达成了完全去除鼠标加速度的方法(鼠标和光标的1:1点对点移动). 并且在所有的游戏里都适用, 从根本上解决问题的办法.
http://www.esreality.com/?a=post&id=1846538
原文在这里, MarkC的win7去加速度解决方案, 我稍微翻译一下
http://www.filefront.com/16520577/MarkC_Windows7_MouseFix.zip/
下载这个
(非win7系统请看5)
1. 如何使用?
-在控制面板里,选择外观与个性化, 选择显示, 看看你选的DPI百分比是100%还是125%或者150%
-在控制面板的设置里, 把鼠标速度的滑块拖在中间 (6/11位置) .
-打开上面下载的zip文件
-选择符合你DPI百分比的那个reg文件, 双击导入(需要管理员权限)
-重启以应用修改
2. 为何需要这个补丁?
首先, 如果你不知道以为什么需要它, 那么你就不需要..
老游戏里, 比如半条命1, 雷神之锤12, 开启游戏后它们会调用一个windows函数, 来禁用掉鼠标加速, 强制光标点对点移动, 在这些游戏里准星的瞄准没有任何问题.
但是XP,Vista,win7里, 游戏不再那么容易的去掉鼠标加速了, windows有时在后台启用鼠标加速, 即使你在控制面板里已经把它关掉.
所谓鼠标加速, 就是说你移动鼠标快, 那同样的距离, 屏幕上的光标会移动的距离更长, 在某些情况下这是非常有用的. 但是在FPS游戏, 这种情况下的瞄准就是一种灾难..
3. 这个怎么工作的?
这个补丁无比牛逼的直接对windows的鼠标加速功能进行修改, 类似于把加速度修改成0, 这样即使游戏中调用了加速函数, 实际上还是鼠标与光标的点对点移动.
4. 如何知道这玩意确实有用?
在上面下载的压缩包中, 有一个MouseMovementRecorder, 鼠标移动记录器. 这个牛逼的东西, 你用了就知道了, 会显示出鼠标移动距离(第一列), 屏幕光标移动距离(第二列), 第三列是频率(不知道是啥), 第四列是说你是否启用了鼠标加速.
可以先试一下修改以前的鼠标加速, 红色是变快–同样的距离, 屏幕移动更远, 绿色是相反. 很明显. 在控制面板里把加速关掉以后再看一看区别.
修改以后, 即使开着鼠标加速, 也是不加速的情况了, 这时不管什么游戏, 任何情况下都无法再加速了
5. 不想用6/11位置, 或者DPI不是那三个中的任何一个, 或者xp/vista怎么搞?
作者做了个自动的工具, 就是压缩包里的MarkC_Windows7+Vista+XP_MouseFix_Builder文件夹, 我没试过, 试过的同学回一下~~
6. 如何卸载?
导入WindowsDefault.reg即可
Ubuntu下东芝T100插耳机外放不停的问题终于有人解决了..
by Viaxl on Jun.14, 2010
吾等菜鸟, 只能苦苦等待高手援助, 买来几个月后的今天, 收到mailing list发来的喜讯..
> I have a t135-s1312 and was able to get my headphone jack to work
> separately from my speakers with this workaround ( which I found on some
> website, I don’t really remember where):
> add:
> options snd-hda-intel model=”olpc-xo-1_5″
>
> to:
>
> /etc/modprobe.d/alsa-base.conf
终于可以把它当大号iPod使了..
[ACM] POJ1837解题报告, 背包..
by Viaxl on Jun.12, 2010
求严格背包, 这次要求是所有物品都必须使用, 问有多少种填满的方法(具体看题)
如果只问能否填满(这样看来又不能把v=重量*杠杆长度看成物品了, 不是传统背包..好难归纳) 那只要用bool型数组记录, 因为不能不用 所以用两个数组更替(a0[i]==true doesn’t mean a1[i]==true, so.)
问有多少种方法把bool换成计数器即可
2010/08/05 Update:
在”能不能放满”(或者填满特定容量) 这种题型中, 以下三种情况是可以让我们求”符合要求的组合有多少种”
1. 一个物品具有多种可选的体积. 比如在本题中是”在物品体积可变, 并且能够为负的情况下, 能不能使占用空间恰为0(平衡)”
2. 物品可以选择不用
3. 1&&2
原因很简单, 上面三种情况的补集是”物品体积固定并且必须全用”, 这种情况最后占用的容积是常数, 逆否命题即上面的蓝字部分成立.
细节:
int *a=(int *)malloc(sizeof(int)*20001); //sizeof(a)==4
int a[20001]; //sizeof(a)==80004;
混淆了一下 导致数组不能初始化, 结果是诡异的3 (答案是2)
debug的时候数组里是非常混乱的 (比如a0[9999]==-265219901)
但是release的时候数组即使不初始化也都为0, 但不一定(诡异的3就是因为某个数==1, 应该初始化为0的, 和内存前面的写入有关吧)
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int *a0,*a1;
int C,G,c[20],g[20];
a0=(int *)malloc(sizeof(int)*20001);
memset(a0,0x00,sizeof(int)*20001);
a0[10000]=1;
scanf("%d%d",&C,&G);
for(int i=0;i<C;i++)
scanf("%d",c+i);
for(int i=0;i<G;i++)
scanf("%d",g+i);
int v;
for(int i=0;i<G;i++) {
a1=(int *)malloc(sizeof(int)*20001);
memset(a1,0x00,sizeof(int)*20001);
/*/debug
for(int k=9900;k<=10100;k++)
if(a0[k])
printf("a0[%d]=%d, ",k,a0[k]);
printf("\n");//*/
for(int j=0;j<C;j++) {
v=g[i]*c[j];
for(int i=19000;i>=1000;i--) //order doesn't make sense.
a1[i+v]+=a0[i];
/*/debug
for(int k=9900;k<=10100;k++)
if(a1[k])
printf("a1[%d]=%d, ",k,a1[k]);
printf("\n");//*/
}
free(a0);
a0=a1;
}
printf("%d\n",a0[10000]);
return 0;
}
欢迎路过~ 

