日历
网志分类
· 所有网志 (163)
· 吃喝 (3)
· 工作 (35)
· 读书 (7)
· 出游 (2)
· music (0)
· 随想 (13)
· 情感 (3)
· 算法练习 (88)
· 生活 (10)
· 未分类 (2)
最新的评论
站内搜索
友情链接
· 我的歪酷 非非共享界
· 芹菜
· Crazyb0y

订阅 RSS

0027546

歪酷博客

芹菜地


lovely *,*   {07/04/30/00:44}


维宽 @ 2008-06-23 21:49

DownThemAll(dTa)是目前firefox下用得最多的下载插件,它支持多线程下载,断点续传等,使用很方便。美中不足的是,dTa对http协议下载支持很好,但对ftp协议下载却几乎没有做任何扩展,跟firefox自带的下载工具功能上几乎没有什么区别,不能暂停,不能断点续传,不支持多线程下载等。但实际上,xunlrunner库里对ftp的实现是完全的,只是因为dTa没有利用到而已。要用到这些功能也很简单,下面就介绍如何更改dTa,使它对ftp的支持更好一些。

首先到dTa这个扩展的目录下,通常是~user/.mozilla/****.default/extensions/{DDC359D1-844A-42a7-9AA1-88A850A938A8} /chrome下,{}中包含的是dTa的当前uuid.

把chrome.jar解压到当前目录, linux下是unzip chrome.jar就行了;再将chrome.jar复制为chrome.orig.jar,以便后面操作失误时可以恢复。

再到当前目录下的content/dta目录下,这里有一个manager.js,它是dta文件下载的核心模块,也是我们要更改的地方。

打开manager.js文件,跳到1693行左右,这里有一个try catch语句块。try部分主要是为了从某一部分开始请求http文件,catch部分为空。在整个catch语句里,我们加上自己对ftp协议的处理,它也是一个try catch语句块:
        try {
            let rc = this._chan.QueryInterface(Ci.nsIResumableChannel);
            rc.resumeAt(c.start+c.written, null);
        } catch(ex) {
        }
这个语句块判断下载的文件是否可以续传,如果可以,就跳到它要续传的位置。

再在文件中跳到2038行左右,这里有一个单独的语句d.resumable=false; 我们要把这句话替换成一个如下的try catch语句块:
        try {
            let rc = this._chan.QueryInterface(Ci.nsIResumableChannel);
            d.resumable = true;
        } catch(ex) {
            d.resumable = false;
        }
它也是判断当前下载文件的可续传性。

保存文件manager.js,退出。我们再回到chrome.jar所在的目录中去,把更新后的manager.js文件加进去.  zip -r chrome.jar content/dta/manager.js。

重新启动firefox,这下dta管理器中的ftp文件就可以被暂停了。由于ftp站点通常限制了同ip的访问数,多线程下载通常用不上。这没关系,反正修改后的dta现在是支持多线程下载和续传了。




 
维宽 @ 2008-02-22 23:47

2166.cpp

#include<iostream> 
using namespace std;
// 最好的就是最简单的,从最小的开始算 1/a + 1/b + 1/c...
// 如果只有一项,直接判断
// 有很多项,则可以分解为1/a + p/q的形式,并且 a*q<=当前限制
int P, Q, A, N;

int gcd(int a, int b){
    int t;
    if(a < b){
        t = a, a = b, b = t;
    }
    while(b!=0){
        t = a % b;
        a = b;
        b = t;
    }
    return a;
}

// 从现在起第一项1/s中 s>=v且s*nq<=a
int count(int v, int p, int q, int a, int n){
    int ret = 0;
    if(p == 1 && q >= v){
        ret++;
    }
    if(n<=1) return ret;
    int t, r, s;
    int np, nq;
    for(s = v; s*s<=a; s++){
        np = p*s-q;
        nq = q*s;
        t = gcd(nq, np);
        nq /= t;
        if(np < 0 || s*nq>a){
            continue;
        }
        np /= t;
        ret += count(s, np, nq, a/s, n-1);
    }
    return ret;
}
void fun(){
    int t = gcd(P, Q);
    P /= t;
    Q /= t;
    int ret = count(1, P, Q, A, N);
    printf("%d\n", ret);
}
int readIn(){
    scanf("%d%d%d%d",&P,&Q,&A,&N);
    return P + Q + A + N;
}
int main(){
    while(readIn() > 0){
        fun();
    }
    return 0;
}






 
维宽 @ 2007-12-09 22:56

使用两个二维数组就可以,设二维数组cur[M][M], nex[M][M], 其中M<=5,
cur[i][j]表示对于当前的串,从现在向前数,0比1多i个,1比0多j个。比如说
串"00110",它的i为1,"00110",j为2, "110"。因此,对于cur[i][j],如果对它后面加上一个"1",则将cur[i][j]加到nex[m][n]上,其中m,n的计算如下
     m = i-1, n = j +1. 如果m<0,将m设为0;如果n>M,则放弃计算。
如果对它后面加个一个"0",计算也类似。

代码如下:
#include<iostream>
using namespace std;
enum {
    SIZ = 6,
};
typedef long long (*D2)[SIZ];
long long tab[2][SIZ][SIZ];
int N, K, lim;
 
void fun(){
    if(N <= K){
        printf("%d\n", 1<<N);
        return ;
    }
    D2 pre, cur, tmp;
    pre = tab[0], cur = tab[1];
    memset(pre, 0, sizeof(tab[0]));
    pre[0][0] = 1;
    int i, a, b, m, n;
    for(i=0; i<N; i++){
        memset(cur, 0, sizeof(tab[0]));
        for(a=0; a<= K; a++){ // count zero
            for(b=0; b<= K; b++){ // count one
                // append zero
                m = a + 1, n = b - 1; 
                if(n < 0) n = 0;
                if(m <= K)
                    cur[m][n] += pre[a][b];
                // append one
                m = a - 1, n = b + 1;
                if(m < 0) m = 0;
                if(n <= K)
                    cur[m][n] += pre[a][b];
            }
        }
        tmp = pre, pre = cur, cur = tmp;
    }
    long long ret = 0;
    for(a=0; a<= K; a++){
        for(b=0; b<=K; b++){
            ret += pre[a][b];
        }
    }
    printf("%lld\n", ret);
}
 
int main(){
 
    while(scanf("%d%d", &N, &K) > 0){
        fun();
    }
 
    return 0;
}
 


 
维宽 @ 2007-12-09 22:38

上了一个新台阶,以后再接再励,登上800题,900题,1000题...


 
维宽 @ 2007-11-17 22:41

计算prior时,要考虑的东西比较多,也不是很明白。  
prior[i][j] = max {
      same[i][k] + opt[k+1][j], if (i==0||chr[i-1]!=chr[k+1]) //因为左边可以绑定,右边的就是自由计算了
      same[i][k] + prior[k+1][j], if (chr[i-1]==chr[k+1]) // 左边不可绑定,先算右边的
} 其中 chr[i]==chr[k]


 
维宽 @ 2007-10-28 12:36

inner[i][j]是指求当color[i-1]==color[j+1]时内部各色球从i到j计算所得的值,它可能被以下三种值所更新:
 1. same[i][j],当color[i] == color[j]时;
 2. same[i][k] + opt[k+1][j],当color[i]==color[k]&&(i==0||color[i-1]!=color[k+1]);
 3. same[i][k] + prior[k+1][j],当color[i]==color[k]&&color[i-1]==color[k+1].
在计算inner[i][j]的值,必须确保它们的外围球i-1,j+1不受影响,即每次计算后,边界球都不能与i-1的颜色相同。


 
维宽 @ 2007-10-22 09:38

    推导式part的计算与same比较类似,估计它们可能可以合并。part[i][j]也与两个条件有关:
1. part[i][j] = inner[i][j-1];
2. part[i][j] = inner[i][k-1] + inner[k+1][j-1], color[k]==color[j]&&len[k]==1&&len[j]==1
注意的是,这里color[i]与color[j]未必同色。


 
维宽 @ 2007-10-18 20:28

当chr[i]==chr[j]时,计算same[i][j],
分两种情况,1)当len[i]==1,且存在k<=j&&k>=i&&chr[k]==chr[i]&&len[k]==1时
                          更新val为消去i,k,j的值
                         更新same[i][j]为val+inner[i+1][k-1]+part[k+1][j]
                      2)当len[i]>=2时,
                         更新val为消去i,j的值
                         更新same[i][j]为val+part[k+1][j]
注意这里没有考虑len[i]>2&&len[j]==1&&len[k]==1时消去的值,是因为在part[][]中会考虑这种情况。


 
维宽 @ 2007-10-15 22:47

在对opt进行计算时,使用的opt推导式如下:
1.opt[i][j] = same[i][j]   当chr[i] == chr[j]时
2.opt[i][j] = same[i][k] + opt[k][j] 当i<=k && k<j &&chr[i]==chr[k]时
opt[i][j]取1,2中的最大值。
opt使用的是从左到右的消去法,假定每次消去的都是最左边的段。
因此,opt的计算又转化成求same的计算了。


 
维宽 @ 2007-10-12 21:54

2127.cpp

#include <stdio.h> 
#include <string.h> 
#include <assert.h> 

inline int sqr(int x){  return x*x ; }
inline int max(int x, int y) {  return x>y?x:y; }
inline int min(int x, int y) {  return x<y?x:y; }

inline void update(int &v, int nv){
    if(v < nv) v = nv;
}

int opt[200][200];  // opt[i][j],i..j之间的最优解
int inner[200][200];// inner[i][j],当i-1,j+1同色时,i..j的最优解
int prior[200][200];// prior[i][j],当i-1,j+1存在时,对i..j优先求解的值
int same[200][200]; // same[i][j], 当i,j同色时,i..j的最优解
int part[200][200]; // part[i][j], 当i-1,j同色时,对i..j-1的最优解

char chr[200];
int len[200];
int n;

int main() {
    int l, i, k, j;
    char cmd[201];
    int ncmd;

    while(scanf("%s", cmd) != EOF) {
        /* parse the input string */
        ncmd = static_cast<int> ( strlen(cmd) );
        n = 0;
        for(i = 0; i < ncmd; ++i) {
            if(cmd[i] == 0 || cmd[i] != cmd[i - 1]) {
                k = i;
            }
            if(i == ncmd - 1 || cmd[i] != cmd[i + 1]) {
                chr[n] = cmd[i];
                len[n] = i - k + 1;
                ++n;
            }
        }

        /* init single char */
        for(i = 0; i < n; ++i) {
            opt[i][i] = sqr(max(len[i], 2) + 1);
            inner[i][i] = sqr(max(len[i], 2) + 1);
            prior[i][i] = -1;
            same[i][i] = sqr(max(len[i], 2) + 1);
            part[i][i] = -1;
        }

        /* from less to more */
        for(l = 2; l <= n; ++l) for(i = 0; i + l <= n; ++i){
            j = i + l - 1;

            /* update same[i][j] */
            same[i][j] = -1;
            if(chr[i] == chr[j]) {
                if(len[i] >= 2) {
                    update(same[i][j], sqr(len[i] + max(len[j], 2)) + part[i + 1][j]);
                } else {
                    for(k = i; k < j; ++k) {
                        if(chr[k] != chr[i] || len[k] != 1)
                            continue;

                        if(k == i) {
                            update(same[i][j], sqr(2 + max(len[j], 2)) + part[k + 1][j]);
                        } else {
                            update(same[i][j], sqr(2 + max(len[j], 2)) + inner[i + 1][k - 1] + part[k + 1][j]);
                        }
                    }
                }
            }

            /* update part[i][j] */
            part[i][j] = -1;
            if(i != 0 && chr[i - 1] == chr[j]) {
                if(len[j] >= 2) {
                    update(part[i][j], inner[i][j-1]);
                } else {
                    for(k = j; k > i; --k) {
                        if(chr[k] != chr[j] || len[k] != 1)
                            continue;
                        if(k == j) {
                            update(part[i][j], inner[i][k-1]);
                        } else {
                            update(part[i][j], inner[i][k-1] + inner[k+1][j-1]);
                        }
                    }
                }
            }

            opt[i][j] = inner[i][j] = prior[i][j] = -1;
            for(k = i; k <= j; ++k) {
                if(chr[k] != chr[i])
                    continue;
                if(k == j) {
                    update(opt[i][j], same[i][j]);
                    update(inner[i][j], same[i][j]);
                    continue;
                }
                /* update opt[i][j] */
                update(opt[i][j], same[i][k]+opt[k+1][j]);

                /* update inner[i][j] and prior[i][j] */
                if(i == 0 || chr[i - 1] != chr[k + 1]) {
                    update(inner[i][j], same[i][k] +opt[k+1][j]);
                    update(prior[i][j], same[i][k] +opt[k+1][j]);
                } else {
                    if(prior[k + 1][j] != -1) {
                        update(inner[i][j], same[i][k] + prior[k+1][j]);
                        update(prior[i][j], same[i][k] + prior[k+1][j]);
                    }
                }

            }
        }

        printf("%d\n", opt[0][n - 1]);
    }
    return 0;
}







 
维宽 @ 2007-10-11 22:50

orignal.cpp

#include <stdio.h> 
 
#include <string.h> 
 
#include <assert.h> 
 
/*

 * 代码来源: http://acm.zjnu.cn/bbs/showt.asp?boardid=2&id=667

 * 其中xxx[i][j]表示i,j同色时最大值

 *    yyy[i][j]表示i,j-1同色时,i..j-1部分能达到的最大值

 *    delta[i][j][0] 表示i,j部分无约束情况下的最大值

 *    delta[i][j][1] 表示i,j部分在i-1,j+1为同色时的最大值

 *    delta[i][j][2] 表示i,j部分在i-1,j+1后消去时的最大值,即i..j部分必须先消去

 */ 



#define sqr(x) ((x) * (x)) 
 
#define max(x, y) ((x) > (y) ? (x):(y)) 
 
#define min(x, y) ((x) < (y) ? (x):(y)) 
 


int delta[200][200][3]; 

int xxx[200][200]; 

int yyy[200][200]; 



char chr[200]; 

int len[200]; 

int n; 



int main() { 

	int l, i, i1, j, k; 

	char cmd[201]; 

	int ncmd; 



	while(scanf("%s", cmd) != EOF) { 

		ncmd = strlen(cmd); 



		n = 0; 

		for(i = 0; i < ncmd; ++i) { 

			if(cmd[i] == 0 || cmd[i] != cmd[i - 1]) { 

				i1 = i; 

			} 

			if(i == ncmd - 1 || cmd[i] != cmd[i + 1]) { 

				chr[n] = cmd[i]; 

				len[n] = i - i1 + 1; 

				++n; 

			} 

		} 



		assert(n >= 1); 

		for(i = 0; i < n; ++i) { 

			delta[i][i][0] = sqr(max(len[i], 2) + 1); 

			delta[i][i][1] = sqr(max(len[i], 2) + 1); 

			delta[i][i][2] = -1; 

			xxx[i][i] = sqr(max(len[i], 2) + 1); 

			yyy[i][i] = -1; 

		} 



		for(l = 2; l <= n; ++l) for(i = 0; i + l <= n; ++i){ 

			j = i + l - 1; 



			xxx[i][j] = -1; 

			if(chr[i] == chr[j]) { 

				if(len[i] >= 2) { 

					if(xxx[i][j] == -1 || sqr(len[i] + max(len[j], 2)) + yyy[i + 1][j] > xxx[i][j]) 

						xxx[i][j] = sqr(len[i] + max(len[j], 2)) + yyy[i + 1][j]; 

				} else { 

					for(i1 = i; i1 < j; ++i1) { 

						if(chr[i1] != chr[i]) 

							continue; 



						if(len[i1] != 1) 

							continue; 



						if(i1 == i) { 

							if(xxx[i][j] == -1 || sqr(2 + max(len[j], 2)) + yyy[i1 + 1][j] > xxx[i][j]) { 

								xxx[i][j] = sqr(2 + max(len[j], 2)) + yyy[i1 + 1][j]; 

							} 

						} else { 

							assert(delta[i + 1][i1 - 1][1] != -1); 

							if(xxx[i][j] == -1 || sqr(2 + max(len[j], 2)) + delta[i + 1][i1 - 1][1] + yyy[i1 + 1][j] > xxx[i][j]) { 

								xxx[i][j] = sqr(2 + max(len[j], 2)) + delta[i + 1][i1 - 1][1] + yyy[i1 + 1][j]; 

							} 

						} 

					} 

				} 

				assert(xxx[i][j] != -1); 

			} 



			yyy[i][j] = -1; 

			if(i != 0 && chr[i - 1] == chr[j]) { 

				if(len[j] >= 2) { 

					assert(delta[i][j - 1][1] != -1); 

					if(yyy[i][j] == -1 || delta[i][j - 1][1] > yyy[i][j]) 

						yyy[i][j] = delta[i][j - 1][1]; 

				} else { 

					for(i1 = j; i1 > i; --i1) { 

						if(chr[i1] != chr[j]) 

							continue; 



						if(len[i1] != 1) 

							continue; 





						if(i1 == j) { 

							assert(delta[i][i1 - 1][1] != -1); 

							if(yyy[i][j] == -1 || delta[i][i1 - 1][1] > yyy[i][j]) 

								yyy[i][j] = delta[i][i1 - 1][1]; 

						} else { 

							assert(delta[i][i1 - 1][1] != -1); 

							assert(delta[i1 + 1][j - 1][1] != -1); 

							if(yyy[i][j] == -1 || delta[i][i1 - 1][1] + delta[i1 + 1][j - 1][1] > yyy[i][j]) 

								yyy[i][j] = delta[i][i1 - 1][1] + delta[i1 + 1][j - 1][1]; 

						} 

					} 

				} 

				assert(yyy[i][j] != -1); 

			} 



			delta[i][j][0] = delta[i][j][1] = delta[i][j][2] = -1; 

			for(i1 = i; i1 <= j; ++i1) { 

				if(chr[i1] != chr[i]) 

					continue; 

				if(i1 == j) { 

					for(k = 0; k <= 1; ++k) { 

						if(delta[i][j][k] == -1 || delta[i][j][k] < xxx[i][j]) 

							delta[i][j][k] = xxx[i][j]; 

					} 

					continue; 

				} 

				if(delta[i][j][0] == -1 || delta[i][j][0] < xxx[i][i1] + delta[i1 + 1][j][0]) 

					delta[i][j][0] = xxx[i][i1] + delta[i1 + 1][j][0]; 

				for(k = 1; k <= 2; ++k) { 

					if(i == 0 || chr[i - 1] != chr[i1 + 1]) { 

						if(delta[i][j][k] == -1 || delta[i][j][k] < xxx[i][i1] + delta[i1 + 1][j][0]) 

							delta[i][j][k] = xxx[i][i1] + delta[i1 + 1][j][0]; 

					} else { 

						if(delta[i1 + 1][j][2] != -1) 

							if(delta[i][j][k] == -1 || delta[i][j][k] < xxx[i][i1] + delta[i1 + 1][j][2]) 

								delta[i][j][k] = xxx[i][i1] + delta[i1 + 1][j][2]; 

					} 

				} 

			} 

			assert(delta[i][j][0] != -1); 

		} 



		printf("%d\n", delta[0][n - 1][0]); 

	} 

	return 0; 

}








 
维宽 @ 2007-10-11 22:38

这个题目是百度之星第二度复赛时所用,难度之大从zju和pku中通过的人数就可以看出。一年多时间里,虽想独立解决它,但一直没有找到头绪,从网上搜索时,也得不到任何帮助。
      在独立解决时,主要有两个问题,
        1 我有一个想当认同的做法,即如果有球不足两个,则补足它对结果只有好处。
        2 同色球被消去,要么是跟另处同色球一起,要么是自己独立消去,但两处同色球消时,里面的球怎么达到最大值
拿到标准代码后,证明第1点是错的,第2点也得到解决。