[Luogu P3226] [BZOJ 2734] [HNOI2012]集合选数

洛谷传送门
BZOJ传送门

题目描述

《集合论与图论》这门课程有一道作业题,要求同学们求出 { 1 , 2 , 3 , 4 , 5 } \{1, 2, 3, 4, 5\} {1,2,3,4,5}的所有满足以 下条件的子集:若 x x x 在该子集中,则 2 x 2x 2x 3 x 3x 3x 不能在该子集中。

同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n ≤ 100000 n\le 100000 n100000,如何求出 { 1 , 2 , . . . , n } \{1, 2,..., n\} {1,2,...,n} 的满足上述约束条件的子集的个数(只需输出对 1 , 000 , 000 , 001 1,000,000,001 1,000,000,001 取模的结果),现在这个问题就 交给你了。

输入输出格式

输入格式:

只有一行,其中有一个正整数 n n n,30%的数据满足 n ≤ 20 n\le 20 n20

输出格式:

仅包含一个正整数,表示 { 1 , 2 , . . . , n } \{1, 2,..., n\} {1,2,...,n}有多少个满足上述约束条件 的子集。

输入输出样例

输入样例#1:
4
输出样例#1:
8

解题分析

一道妙妙的题, 提出所有的质数和 1 1 1, 然后横向每次 × 2 \times 2 ×2, 纵向每次 × 3 \times 3 ×3, 就像下面这样:

1 2 4 8 16...
3 6 12 24 48...
9 18 36 72 144...
......

然后我们可以发现对于一个数, 其右边和下面的数不能出现, 那么就可以预处理出每行有几个数和所有合法状态, 状压 D P DP DP就好了。

代码如下:

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <cstring>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 100500
#define ll long long
#define MOD 1000000001
int n, tot, crs, ans = 1;
int stat[21], avai[4205], dp[21][4205], hd[21];
bool vis[MX];
IN void add(R int ad, int &tar)
{
	tar += ad;
	if (tar > MOD) tar -= MOD;
}
int main(void)
{
	R int i, j, k, l, pre, res, tim;
	scanf("%d", &n); int bd;
	for (i = 0, bd = (1 << (int)log2(n) + 1) - 1; i <= bd; ++i)
	{
		if ((i & (i << 1))) continue;
		avai[++tot] = i;
	}
	for (i = 1; i <= n; ++i)
	{
		if (vis[i]) continue;
		for (j = 1; j <= crs; ++j)//reset
		{
			for (k = 1; avai[k] <= stat[j] && k <= tot; ++k) dp[j][k] = 0;
			stat[j] = 0;
		}
		crs = res = 0;
		for (j = i; j <= n; j = j * 3)
		hd[++crs] = j;
		for (j = 1; j <= crs; ++j)
		{
			for (k = hd[j], tim = 1; k <= n; k <<= 1, tim <<= 1)
			stat[j] |= tim, vis[k] = true;
		}
		dp[0][1] = 1;
		for (j = 1; j <= crs; ++j)
		{
			pre = j - 1;
			for (k = 1; avai[k] <= stat[j] && k <= tot; ++k)
			{
				for (l = 1; avai[l] <= stat[pre] && l <= tot; ++l)
				{
					if (!((avai[k]) & avai[l]))
					add(dp[pre][l], dp[j][k]);
				}
			}
		}
		for (R int j = 1; avai[j] <= stat[crs] && j <= tot; ++j) add(dp[crs][j], res);
		ans = 1ll * ans * res % MOD;
	}
	printf("%d", ans);
}

使用GVF域和VFC域进行图片分割 % Vector field convolution (VFC) external force field example. % % See also AMT, EXAMPLE_PIG, AM_VFC, AM_VFK, AC_DISPLAY. % % Reference % [1] Bing Li and Scott T. Acton, "Active contour external force using % vector field convolution for image segmentation," Image Processing, % IEEE Trans. on, vol. 16, pp. 2096-2106, 2007. % [2] Bing Li and Scott T. Acton, "Automatic Active Model % Initialization via Poisson Inverse Gradient," Image Processing, % IEEE Trans. on, vol. 17, pp. 1406-1420, 2008. % % (c) Copyright Bing Li 2005 - 2009. clear all disp('======================================') disp('Vector field convolution (VFC) example') %% parameter settings disp('Initializing parameters ...') SAVE_AVI = 0; % set it to 1 if you want to save the process as .avi movie DISPLAY_STREAMLINE = 0; % set it to 1 if you want to plot streamlines, note that it takes a while mu = .2; GVF_ITER = 100; normalize = 1; alpha = .5; beta = 0; tau = .5; SNAKE_ITER = 5; SNAKE_ITER1 = 60; RES = .5; clr = {'b' 'b' 'r'}; %% Read images disp('Reading images ...') U = imread('im_U.bmp'); noisyU=imread('im_Unoisy.bmp'); figure(1) %% compare 3 different cases for cs = 1:3, %% compute external force fields switch cs, case 1, % traditional GVF with Gaussian filter disp('--------------------------------------------------') disp('Case 1: GVF snake with initial circle close to FOI') disp('Computing the external force field ...') h = fspecial('gaussian',[5 5],5); f = imfilter(double(noisyU),h); titl = 'GVF'; Fext = AM_GVF(f, mu, GVF_ITER, normalize); R = 20; case 2, % traditional GVF with Gaussian filter disp('--------------------------------------------------') disp('Case 2: GVF snake with initial circle far away from FOI') disp('Computing the external force field ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值