SRM 590 DIV1

转载请注明出处,谢谢

viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

水水更健康,最终回到1800+了。。。

DIV2 1000pt

显然每一列是独立的。分开考虑。

对于某一列。假设按单个字符U , D从下往上考虑的话。发现连续两个U的话。以下的U能够移动的位置受上面一个影响。

只是因此能够想到相邻的U , D互相限制位置,能够依次处理。相邻同样字符的话。 能够作为一个字符。

做法:把相邻的U合并,相邻的D合并。dp[i][j]表示前i个部分处理完。第i个部分最靠上的一个位置为j。

这种话,假设当前为U。那么向上移动的最远位置为下一个部分最靠下的D的位置。

假设当前为D。那么向下移动的最远位置便是上一个部分最靠上的U的位置。

这样就能够搞出每个部分的上下界,然后分别DP。

typedef long long LL;
const LL MOD = 1000000007;
const int N = 55;
LL dp[N][N];
void add (LL &a , LL b) {
	a += b;
	a = (a % MOD + MOD) % MOD;
}
LL mut (LL a , LL b) {
	a = a * b % MOD;
	a = (a + MOD) % MOD;
	return a;
}
LL gao_up (vector<int>&v , int limit) {
	int n = v.size();
	LL c[N][N]; memset (c , 0 , sizeof(c));
	c[n - 1][limit - 1] = 1;
	for (int i = n - 2 ; i >= 0 ; i --) {
		for (int j = limit ; j >= 0 ; j --) {
			if (c[i + 1][j] == 0) continue;
			for (int k = v[i] ; k < j ; k ++) {
				add (c[i][k] , c[i + 1][j]);
			}
		}
	}
	LL ans = 0;
	for (int i = 1 ; i <= limit ; i ++) {
		add (ans , c[0][i]);
	}
	return ans;
}
LL gao_down (vector<int>&v , int down , int up) {
	int n = v.size();
	LL c[N][N]; memset (c , 0 , sizeof(c));
	c[0][down] = 1;
	for (int i = 0 ; i < n ; i ++) {
		for (int j = 0 ; j <= up ; j ++) {
			if (c[i][j] == 0) continue;
			for (int k = j + 1 ; k <= v[i] ; k ++)
				add (c[i + 1][k] , c[i][j]);
		}
	}
	return c[n][up];
}
vector<vector<int> > v;
class FoxAndShogi {
public:
int differentOutcomes(vector <string> board) {
    int row = board.size() , col = board[0].size();
    LL ans = 1LL;
    for (int c = 0 ; c < col ; c ++) {
    	memset (dp , 0 , sizeof(dp));
    	string s = "";
    	v.clear ();
    	for (int r = row - 1 ; r >= 0 ; r --)
    		s = s + board[r][c];
    	int first = -1;
    	for (int i = 0 , pre = -1 ; i < s.size() ; i ++) {
    		if (s[i] == ‘.‘) continue;
    		if (s[i] == ‘D‘ && pre == 0) {
    			v[v.size() - 1].push_back (i + 1);
    		}
    		else if (s[i] == ‘U‘ && pre == 1) {
    			v[v.size() - 1].push_back (i + 1);
    		}
    		else {
    			if (first == -1) {
    				if (s[i] == ‘U‘) first = 0;
    				else first = 1;
    			}
    			vector<int>t;
    			t.push_back(i + 1);
    			v.push_back(t);
    			if ( s[i] == ‘U‘) pre = 1;
    			else pre = 0;
    		}
    	}
    	dp[0][0] = 1;
    	for (int i = 0 ; i < v.size() ; i ++) {
    		for (int j = 0 ; j <= row ; j ++) {
    			if (dp[i][j] == 0) continue;
     			// up
    			if ((first == 0 && i % 2 == 0) || (first == 1 && i % 2 == 1)){
    				int now = v[i][v[i].size() - 1];
    				int limit = (i + 1) < v.size() ? v[i + 1][0] : (col + 1);
    				for (int k = now ; k < limit ; k ++) {
    					add (dp[i + 1][k] , mut (dp[i][j] , gao_up (v[i] , k + 1)));
    				}
    			}
    			//down
    			else {
    				int now = v[i][v[i].size() - 1];
    				for (int k = j + 1 ; k <= now ; k ++) {
    					add (dp[i + 1][k] , mut (dp[i][j] , gao_down (v[i] , j , k)));
    				}
    			}
    		}
    	}
    	LL tmp = 0;
    	for (int i = 0 ; i <= row ; i ++)
    		add (tmp , dp[v.size()][i]);
    	// cout << tmp << endl;
    	ans = mut (ans , tmp);
    }
    return ans;
}
};

DIV1 250PT

把L,R所有提取出来,先推断下是否一致。

然后 比較下位置

DIV1 500 PT

异或结果 小于等于LIMIT,先处理相等的情况,既异或结果每一位都和LIMIT相等,列方程组,求一下秩。

否则的话。必定存在某一位,LIMIT中为1。实际为0,并且高位和LIMIT一致,低位随意 。

所以枚举相隔的这个位置。相同是列方程组求解。

typedef long long LL;
int a[100][100];
int n , m ;
long long gauss(){    int i,j,row=1,col;
    for (col=1;col<=m;++col){
        for (i=row;i<=n;++i)
            if (a[i][col])
                break ;
        if (i>n)
            continue ;
         if (i!=row){
            for (j=col;j<=m;++j)
                swap(a[row][j],a[i][j]);
            swap(a[i][m + 1],a[row][m + 1]);
        }
        for (i=row+1;i<=n;++i)
            if (a[i][col]){
                for (j=col;j<=m;++j)
                    a[i][j]^=a[row][j];
                a[i][m + 1]^=a[row][m + 1];
            }
        ++row;
     }
    for (i=row;i<=n;++i)
        if (a[i][m + 1])
            return 0;
    return 1ll<<(long long)(m-row+1);
 }
class XorCards {
public:
long long numberOfWays(vector<long long> number, long long limit) {
    LL ans = 0;
    m = number.size();n = 61;
    memset (a , 0 , sizeof(a));
    for (int i = 0 ; i < 61 ; i ++) {
    	for (int j = 0 ; j < m ; j ++) {
    		if (number[j] & (1LL << i)) a[i + 1][j + 1] = 1;
    	}
    	a[i + 1][m + 1] = (limit & (1LL << i)) ? 1 : 0;
    }
    ans = gauss ();
    for (int i = 0 ; i < 61 ; i ++) {
    	if (!(limit & (1LL << i))) continue;
    	memset (a , 0 , sizeof(a));
    	for (int j = i + 1 ; j < 61 ; j ++) {
    		for (int k = 0 ; k < m ; k ++) {
    			if (number[k] & (1LL << j)) a[j + 1][k + 1] = 1;
    		}
    		a[j + 1][m + 1] = (limit & (1LL << j)) ? 1 : 0;
    	}
    	for (int k = 0 ; k < m ; k ++) {
    		if (number[k] & (1LL << i)) a[i + 1][k + 1] = 1;
    	}
    	ans += gauss ();
    }
    return ans;
}
};

DIV1 1000PT

排序方式价格优势,然后 镶上每次迭代暴力,folyd寻求最短的价格后,值。。

时间: 2024-10-18 00:31:48

SRM 590 DIV1的相关文章

topcoder srm 590 div1

problem1 link 对于每一个,找到其在目标串中的位置,判断能不能移动即可. problem2 link 如果最后的$limit$为$11=(1011)_{2}$,那么可以分别计算值为$(1011)_{2},(1010)_{2},(100x)_{2},(0xxx)_{2}$的答案数,$x$位置表示可以为任意.也就是可以忽略这些位. 当答案固定时,可以用高斯消元求解. problem3 link 令$d(i,j)$表示点 $i$到点$j$的距离. 使用最小割求解.将每个点拆成$n$个点,第

Topcoder SRM 643 Div1 250&lt;peter_pan&gt;

Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*......*pn,我们假设p0,p1,...,pn是单调不降的,那么v里存储的是下标为偶数 的N的质因数p0,p2,p4,...,p(2k).现在要求写一个程序,返回一个vector<long long>ans; ans里存储的是p0,p1,p2,...,pn. Limits Time Limit(m

SRM 618 DIV1 500

非常棒的组合问题,看了好一会,无想法.... 有很多做法,我发现不考虑顺序的最好理解,也最好写. 结果一定是两种形式 A....A   dp[n-1] A...A...A sgma(dp[j]*dp[n-j-1])( 1<=j<=n-2) 最后乘上n! 什么时候才能自己在比赛中做出一个500分来啊!!! class LongWordsDiv1 { public : int count(int n) { int i,j; fact[0] = 1; for(i = 1; i <= n; i

SRM 631 DIV1

SRM 631 DIV1 A:最多肯定只需要两步,中间的两行,一行黑,一行白就可以了,这样的话,只需要考虑一开始就满足,和枚举一行去染色满足的情况就可以了,暴力即可 B:贪心,一个记录当前有猫的位置和当前超过一只猫的位置,然后位置排序从左往右找,如果当前能移动到之前超过两只的位置,就全部移动过去,不增加,如果不行,那么考虑当前这个能不能铺成一条,如果可以,相应更新位置,如果不行,就让猫全部堆到右边右边去,然后堆数多1 代码: A: #include <iostream> #include &l

SRM 622 div1 250

Problem Statement    In the Republic of Nlogonia there are N cities. For convenience, the cities are numbered 0 through N-1. For each two different cities i and j, there is a direct one-way road from i to j. You are given the lengths of those roads a

SRM 587 DIV1

550 结论:同一层的交点共线. 很容易猜到,也可以跑几组数据验证. 利用结论就可以按层算,再利用对称性简化计算. 1 using namespace std; 2 #define maxn 70100 3 class TriangleXor { 4 public: 5 int theArea(int); 6 }; 7 double l[maxn] , x[maxn] , y[maxn] , H; 8 int idx; 9 10 void addpoint(double k,double w)

Topcoder SRM 648 Div1 250

Problem 给一个长度为N的"AB"字符串S,S只含有两种字符'A' 或 'B',设pair(i,j)(0=<i<j<N)表示一对 i,j 使得S[i]='A',S[j]='B'.现给定一个K,求字符串S,使得pair(i,j)的个数恰好为K.若不存在,则返回空串. Limits Time Limit(ms): 2000 Memory Limit(MB): 256 N: [2, 50] K: [0 , N*(N-1)/2 ] Solution 若K>(N/2

Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

Problem Statement      The Happy Letter game is played as follows: At the beginning, several players enter the field. Each player has a lowercase English letter on their back. The game is played in turns. In each turn, you select two players with dif

[TC SRM 697 div1 lev1] DivisibleSetDiv1

Tutorial:https://apps.topcoder.com/wiki/display/tc/SRM+697#DivisibleSetDiv1 Note:证明过程值得一看. 主要内容:寻找[x1,x2,...,xn]使得满足bi * xi >= S - xi,其中S = x1 + x2 + ... + xn.