发现用记忆化搜索写数位DP 比较好写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97/* ZOJ 3416 数位DP
* 一个数是Balanced ,指这个数的力矩为0
* 如 4139 选支点为3 4*2 + 1*1 = 9*1
* 为[x,y]内有多少个Balanced Number 0<=x<=y<=10^18
*
* watashi的博客里提到如果 <=10^9 用 sqrt(n)的方法打表,
* 打印每10w个数之间有多少个Balanced Number
* 感觉这种方法很好 sqrt(n)
*
* 这题数据规模很大10^18,要用数位统计
*
* dp的预处理我想的少了一位,最后问别人
* dp[all,len,total] 表示总长度为all,字符占的长度为len,力矩为total的方案数
* 如xxx123 即是 dp[6,3,1*3+2*4+3*5]
*
* init后,就用数位统计cal(x)统计[0,x]内多少个Balanced Number
* 枚举位数,枚举该位小于bit[i]的数字j
* 然后再枚举支点位置,1到len 然后统计
* (枚举的位置是1到len,第一次遇到枚举的位置可以是pre的东西)
*
* 由于一个数的支点只有一个!!!所以不会重复计数
* "就会发现一个数最多关于一个digit是balanced的
* (一个严格单调函数最多有一个零点)。
* 注意到了这一点就会知道,这题是不存在重复计算这种问题的。"
*
* 但注意的是0的支点不止一个,所以要减去重复的0
* 000000 支点任意一个都可以
* */
using namespace std;
const int INF = ~0u>>1;
typedef pair <int,int> P;
int dig[20];
ll dp[20][20][10000];
void init(){
memset(dp,-1,sizeof(dp));
}
ll dfs(int pos,int bal,int prenum,bool islim){
if (prenum < 0) return 0;//从后向前枚举的所以不能小于0
if (pos == -1) return prenum == 0;
if (!islim && dp[pos][bal][prenum] != -1){
return dp[pos][bal][prenum];
}
int end = islim ? dig[pos] : 9;
ll ans = 0;
for (int i = 0; i <= end; i++){
ans += dfs(pos-1,bal,prenum+(pos-bal)*i,islim && i == end);
}
if (!islim)
dp[pos][bal][prenum] = ans;
return ans;
}
ll cal(ll n){
int num = 0;
while (n){
dig[num++] = n % 10;
n /= 10;
}
ll ret = 0;
for (int i = 0; i < num; i++)
ret += dfs(num-1,i,0,1);
return ret-num+1;//因为0的支点可以整个数的数位减去重复的
//比如00000支点任意一个都可以
}
int main(){
int t;
init();
ll l,r;
for (scanf("%d", &t); t--;){
cin >> l >> r;
cout << cal(r) - cal(l-1) << endl;
}
return 0;
}
POJ 2796 Feel Good (单调队列)
想了半天愣是搞不定怎么写
4
2 3 4 3
为什么这样可以用单调队列搞呢维护一个不降的序列
把2 3 4 分别入栈,然后遇到3 了,发现不能继续做了,于是先算以最上面4的那个数作为区域最小的那个数能不能实现tmp < ans,之后把4弹出
然后看3发现不小了就继续。
之后遇到-1 数组最后值为-1,那么就是说一直弹栈到最后,把每个在栈的数作为最小的数来进行算tmp
1 | /* POJ 2796 单调队列 维护一个单调不降的序列,然后每次遇到比top小的数时进行 |
博弈论 —— 游戏图与 SG 函数
原网址:https://www.chenyajun.com/2010/06/23/5078
前面几节谈到的游戏可以用图理论来描述,考虑一个图 G = (X, F);其中 X 是顶点,也是先前游戏中可能的态势。F 是一个函数,对于 X 中的任意一个 x,F(x) 的值都出现在 X 中,对于 X 的一个元素 x,F(x) 的含义是一个玩家从 x 出发可以移动到的局势。
对于一个两人的类似前面的游戏而言,可以在一个如此这样的图上进行博弈,首先指定一个起始点 x0,并使用下面的规则:
(1)玩家 I 从 x0 开始首先移动;
(2)玩家交替移动;
(3)在 x 态势时,玩家要将态势转移到另一个态势 y,其中 y 是 F(x) 中的元素。
为简单起见,假定图中不存在环,元素个数为 n,其中最长的一条路径也不超过 n。那么对于前面我们分析的减法游戏,其中 S = {1, 2, 3}。假定游戏中指定对 n 进行减法操作。X = {0, 1, 2…, n} 是图顶点。F(0) 是空集。F(1) = {0},F(2) = {0, 1}。 对于 2<= k <= n,F(k) = {k -3, k -2, k -1}。
因此这个游戏的图大致如下。其中 n = 10。
边的方向代表了可能的移动。
SG 函数
这种图可以通过分析 SG 函数来分析。
所谓图 (X, F) 的 SG 函数 g 是定义在 X 上的一个函数。
g(x) = min{n ≥ 0 : n ≠ g(y) for y ∈ F(x)}。换句话说,g(x) :是一个非负整数;尽可能的小;不出现在 x 的后缀节点的 g 函数取值中。
这是一个递归定义。但可以通过倒推来取得节点的值。对于终点 x,g(x) = 0,因为 F(x) 是空集。
如果一个态势的 g(x) = 0 那么它就是 P 态,否则就是 N 态。
下面的图描述了 g 函数的求解过程,在开始所有的顶点本是没有数字的。在开始,所有的终点 SG 函数值为 0,一共有 4 个终点,它们位于图的左边和下边。对于点 a,它的后缀 SG 函数为 0,那么它自身的 SG 值就是 1,它是所有没有出现在 a 后缀节点的 SG 值的最小值。那么 b 的 SG 值就是 2,因为它有 2 个后缀,一个是 a,令一个是终点,它们的 SG 值分别是 1 和 0,那么它的 SG 值就是 2。那么 c 的 SG 值就是 0,因为 c 只有一个后缀 a,而 a 的 SG 值为 1,那么没有出现在 c 后缀节点的 SG 值的最小值就是 0。
对于 S = {1, 2, 3} 的减法游戏其 SG 函数是多少?
终点 0, SG 值为 0, 1 只能移到 0,而 g(0) = 0,所以 g(1) = 1,同样,2 可以移动到 0 和 1,而 g(0) = 0,g(1) = 1,故 g(2) = 2,3 可以移动到 0,1,2 ,它们各自的 g(0) = 0, g(1) = 1, g(2) = 2,因此 g(3) = 3,但是对于 4 只能移动到 1,2,3,其各自的 SG 值为 1,2,3,故 g(4) = 0。
容易发现 g(x) = x( mod 4)。
考虑一种移石子游戏:每次必须移走至少剩余的一半,我们可以如下计算 SG 函数:
x 0 1 2 3 4 5 6 7 8 9 10 11 12 . . . g(x) 0 1 2 2 3 3 3 3 4 4 4 4 4 . . .
g(x) = min{k: power(2,k) > x}。
Tank_War 大一课程设计更新报告
第一次写这样的项目,用VS的cpp写的比较简单,先放一个下载文件
http://pan.baidu.com/share/link?shareid=694816596&uk=168774939
要添加一个easyx的库,非常不安全,以后不这样的,这次敢时间
首先遇到了加载过多dll的问题,可以写出一个.reg文件里面内容是如下,再添加进注册表就行了
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorer] "AlwaysUnloadDLL"="1"
VS出现了unsafe,貌似是error C4996,你用了getch什么的就不让你编译通过,可以去网上搜一个解决方案,getch的问题改成_getch就可以编译通过了,见如下
<span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; ">菜单: </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; "> </span><wbr style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; " /><span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; ">项目 | 属性 | 配置属性 | C/C++ | 命令行 | 附加选项(其他选项),加入【/D"_CRT_SECURE_NO_DEPRECATE" 】(注:加入中括号中完整的内容)</span>
<span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px; line-height: 26px; ">或者_CRT_SECURE_NO_WARNINGS,不过不建议,这样就全部都没了</span>
POJ 1082 Calendar Game (博弈)
1 | /* 博弈论题目可以用寻找必败状态的方法解决。 |
VS2012 出现加载很多dll文件 导致编译非常长
做VS项目的时候, 据说因为我的程序出BUG了,就导致VS莫名其妙出现加载很多DLL,编译很久都不显示界面,而且还非常卡
最后找到了一个解决方案。
可以通过修改添加一个注册表文件,使得VS不会出现加载过多DLL的情况
新建一个文本文件,用vim或者sublime打开添加如下
1 | Windows Registry Editor Version 5.00 |
然后保存成*******.reg
文件就可以了**
是你随机文件名
然后打开就行了
Ubuntu 双显示器 分辨率过低
外接显示器可能无法被Ubuntu检测,显示是未知然后,分辨率最高也就1024 * 768 。
可以通过下面方法修改
一.只是本次需要,关机之后回复原来状态
(1)首先使用xrandr命令查看能检测到的分辨率
Screen 0: minimum 320 x 200, current 3286 x 1080, maximum 8192 x 8192 LVDS1 connected 1366x768+0+312 (normal left inverted right x axis y axis) 344mm x 194mm 1366x768 60.0*+ 40.1 1360x768 59.8 60.0 1024x768 60.0 800x600 60.3 56.2 640x480 59.9 VGA1 connected 1920x1080+1366+0 (normal left inverted right x axis y axis) 0mm x 0mm 1024x768 60.0 800x600 60.3 56.2 848x480 60.0 640x480 59.9
可以看到目前有两个一个LVDS1是我笔记本的,一个VGA1是我外接的显示器
(2)然后需要用xrandr命令新增加显示模式,用cvt获得显示模式
cvt X Y H
X表示宽度,Y表示高度,H表示显示器的HZ这个可以查看你的显示器的参数,我是1920*1080 60hz的,命令为
cvt 1920 1080 60
得到
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz Modeline "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
(3)之后把cvt得到的模式用xrandr命令添加,终端输入(具体按照你自己得到的模式输入)
xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync xrandr --addmode VGA1 "1920x1080_60.00" xrandr --output VGA1 --mode 1920x1080_60.00 xrandr --output VGA1 --right-of LVDS1
(4)这样直接就可以显示出效果了
二,每次开机都能这样配置的方法
(1)在你自己的主文件夹形成一个display.sh的文件里面输入
#!/bin/bash xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync; xrandr --addmode VGA1 "1920x1080_60.00"; xrandr --output VGA1 --mode 1920x1080_60.00; xrandr --output VGA1 --right-of LVDS1;
(2)打开终端输入
cd /etc/ sudo gedit profile
(3)在打开的profile文件里加一句
~/display.sh
(4)重启看看效果
求多边形费马点 POJ 2420 A Star not a Tree?
随机选取一个点,再取一个步长,朝这个方向走,如果新位置到各点距离比原来小,则走过去。直到走不动为止,再缩小步长。直到步长小于题目精度。
1 | /* poj 2420 多边形费马点 用模拟退火法 逼近 |
集合的幂集
/* * * */ #include#include #include #include #include #include #include #include using namespace std; const int INF = ~0u>>1; typedef pair P; #define MID(x,y) ((x+y)>>1) #define iabs(x) ((x)>0?(x):-(x)) #define REP(i,a,b) for(int i=(a);i<(b);i++) #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define pb push_back #define mp make_pair #define print() cout<<"--------"< = len){ if (b[0]) cout << b << endl; else cout << "空集" << endl; } else { x = s[i]; k = strlen(b); b[k] = x; GetPowerSet(i+1,s); b[k] = 0; GetPowerSet(i+1,s); } } int main(){ while (~scanf("%s",a)){ printf("%s的幂集是:n", a); print(); GetPowerSet(0,a); print(); } return 0; }
实现之后 sdfea sdfea的幂集是: -------- sdfea sdfe sdfa sdf sdea sde sda sd sfea sfe sfa sf sea se sa s dfea dfe dfa df dea de da d fea fe fa f ea e a 空集 --------
**<span style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline; color: rgb(255, 102, 0); background-position: initial initial; background-repeat: initial initial;">集合A的幂集是由集合A的所有子集所组成的的集合。</span>**
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">若是集合,则的全部子集如下:</span></span>
(空集)</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
因此
的幂集为</span>
- , , , , , , , 。
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">幂集中的每个元素是一个集合,它或是空集,或含集合A中一个元素,或含集合A中两个元素…… 或等于集合A。反之,从集合A 的每个元素来看,它只有两种状态:它或属幂集的无素集,或不属幂集的元素集。则求幂集p(A)的元素的过程可看成是依次对集合A中元素进行"取舍"的过程,并且可以用一棵二叉树来表示过程中幂集元素的状态变化过程,树中的根结点表示幂集元素的初始状态(空集);叶子结点表示它的终结状态,而第i层的分支结点,则表示已对集合A中前i-1个元素进行了取舍处理的当前状态(左分支表示取,右分支表示舍 )。因此求幂集元素的过程即为先序遍历这棵状态树的过程。</span></span>
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">若是有限集,有个元素,那么的幂集有个元素。(其实可以——电脑也如此做——将的元素表示为_n_位二进制数;第_n_位表示包含或不含的第_n_个元素。这样的数总共有个。)</span></span>
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">我们也可以考虑无穷集的幂集。以[康托尔对角线方法](http://zh.wikipedia.org/wiki/%E5%BA%B7%E6%89%98%E7%88%BE%E5%B0%8D%E8%A7%92%E7%B7%9A%E6%96%B9%E6%B3%95 "康托尔对角线方法")可证明集合(不论是否无穷)的幂集的[基数](http://zh.wikipedia.org/wiki/%E5%9F%BA%E6%95%B8 "基数")总是大于原来集合的基数(粗略的说,集合的幂集大于集合本身)。例如[自然数](http://zh.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%95%B8 "自然数")集的幂集可以[一一对应](http://zh.wikipedia.org/wiki/%E5%8F%8C%E5%B0%84 "双射")于[实数](http://zh.wikipedia.org/wiki/%E5%AF%A6%E6%95%B8 "实数")集(把一个无穷0-1序列等同于有1出现的指数的集)。</span></span>
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">集合的幂集,加上并、交和补运算,就得出[布尔代数](http://zh.wikipedia.org/wiki/%E5%B8%83%E5%B0%94%E4%BB%A3%E6%95%B0 "布尔代数")的原始例子。我们可以证明所有有限布尔代数都是同构于某有限集的幂集的布尔代数。这结果虽然对无穷布尔代数不成立,但是所有无穷布尔代数都是某个幂集布尔代数的子代数。</span></span>
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">集合的幂集与对称差运算构成一个[阿贝尔群](http://zh.wikipedia.org/wiki/%E9%98%BF%E8%B2%9D%E7%88%BE%E7%BE%A4 "阿贝尔群")(其中空集为幺元,每个集合的逆元为其本身),而与交运算则构成[交换](http://zh.wikipedia.org/wiki/%E4%BA%A4%E6%8F%9B%E5%BE%8B "交换律")[半群](http://zh.wikipedia.org/wiki/%E5%8D%8A%E7%BE%A4 "半群")。因此(可证明这两运算适合分配律)这两个运算使幂集成为一个[环](http://zh.wikipedia.org/wiki/%E7%92%B0 "环")。</span></span>
<span style="font-size:14px;"><span style="font-family:trebuchet ms,helvetica,sans-serif;">部分来源:</span></span>[http://www.wutianqi.com/?p=1157](http://www.wutianqi.com/?p=1157)
实现代码
Ubuntu 如何看Rmvb Avi 等格式的视频
之前一直用Ubuntu自带的那个电影播放器,每次播放都弹出一个python更新的界面,可是每次都是不成功,后来就做罢了,看电影就换Windows。实在受不了,就研究了下。
<span style="line-height: 1.6em;">1.最省事的最方便的就是用VLC,我一直在用VLC,一直觉得非常好用,就听听歌就行了的就用用吧。VLC直接打开就能播放。你可以直接在软件源找到它然后安装。</span>
sudo apt-get install vlc
<span style="line-height: 1.6em;">2.也可以用Mplayer不过这个需要内核和一个前端,解码器,依次输入</span>
sudo apt-get install mplayer
sudo apt-get install smplayer
sudo apt-get install smplayer-themes
最后一句可有可无,安装两个就能播放
当然如果需要解码器,目前还没有遇到这样的情况,遇到了再写