zoukankan      html  css  js  c++  java
  • 题解 UVa10237

    题目大意 多组数据,每组数据给定两个整数 (n,k),输出在 (n imes n) 的棋盘上放置 (k) 个互不攻击的象的不同方式(象攻击两条斜线上的棋子)。

    分析 我们把棋盘翻转 (frac{pi}4),会形成一个新的 (2n-1) 行的斜棋盘,那么每个象可以攻击同一行同一列的棋子,发现可以递推答案。

    我们考虑先把奇数行和偶数行分开编号讨论,下以奇数行为例。我们从短的行枚举到长的行,用 (f[1][i][j]) 表示奇数行到第 (i) 行一共放了 (j) 个象的总方案数。那么有

    [f[1][i][j] = f[1][i-1][j]+f[1][i-1][j-1]*(len_i-j+1) ]

    最后统计结果就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int n, k;
    ll ans, f[2][65][35];
    
    int main()
    {
    	while(~scanf("%d%d", &n, &k) && !(!n && !k)) {
    		memset(f, 0, sizeof f);
    		
    		ans = 0;
    		
    		f[1][0][0] = f[0][1][0] = 1;
    		for(int i = 1; i <= n; ++i) {
    			int len = i - !(i & 1);
    			
    			f[1][i][0] = 1;
    			for(int j = 1; j <= len && j <= k; j++)
    				f[1][i][j] = f[1][i - 1][j] + (len - j + 1) * f[1][i - 1][j - 1];
    	  	}
    	  	
    		for(int i = 2; i <= n; i++) {
    		  	int len = i - (i & 1);
    		  	
    			f[0][i][0] = 1;
    			for(int j = 1; j <= len && j <= k; j++) {
    				f[0][i][j] = f[0][i - 1][j] + (len - j + 1) * f[0][i - 1][j - 1];
    			}
    		}
    		
    		for(int i = 0; i <= k; i++)
    			ans += f[1][n][i] * f[0][n][k - i];
    		
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    【LOJ】#6432. 「PKUSC2018」真实排名
    【Codechef】BB-Billboards
    【BZOJ】4361: isn
    【BZOJ】4380: [POI2015]Myjnie
    【BZOJ】4292: [PA2015]Równanie
    【LOJ】#121. 「离线可过」动态图连通性
    【BZOJ】4025: 二分图
    【LOJ】#2230. 「BJOI2014」大融合
    【SPOJ】QTREE6-Query on a tree VI
    小白初理解树状数组
  • 原文地址:https://www.cnblogs.com/whx1003/p/12342810.html
Copyright © 2011-2022 走看看