2016_1_17_第二题

这道题调了大概一个多小时终于过了,有许多地方我希望记清楚,我还是记下来。

先给上代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 using namespace std;
 7 const int N = 3003;
 8 int n;
 9 int prime[N],pd,t,record[N];
10 bool vis[N];
11 int small[N],ts,tot;
12 int big[N],tb;
13 int biao[603][1003],size[1003];
14 long long dp[(1<<16)+10][603];
15 void dfs(int i,int linshi,int t,long long kk) {
16     if(t > ts) return;
17     if(kk*small[t]<=n) {
18         biao[i][++size[i]] = linshi+(1<<(t-1));
19         dfs(i,linshi+(1<<(t-1)),t+1,kk*small[t]);
20         dfs(i,linshi,t+1,kk);
21     }
22 }
23 inline void solve(int n) {
24     int k;
25     for(int s = 2 ; s <= n ; ++s) {
26         if(!vis[s]) prime[++t] = s;
27         for(int j = 1 ; j <= t && (k=prime[j]*s)<=n ; ++j) {
28             vis[k] = true;
29             if(s%prime[j]==0) break;
30         }
31     }
32     for(int i = 1 ; i <= n ; ++i) {
33         int linshi = i;
34         for(int j = 1 ; j <= t && linshi!=1 ; ++j) {
35             while(linshi%prime[j]==0 && linshi!=1) {
36                 linshi/=prime[j];
37                 record[prime[j]]++;
38             }
39         }
40     }
41     pd = sqrt(n);
42     for(int i = 1 ; i <= n ; ++i) {
43         if(record[i]%2==1) {
44             if(i<pd) small[++ts] = i;
45             else big[++tb] = i;
46         }
47     }
48     tot = ts+tb;
49     for(int i = 1 ; i <= ts ; ++i) dfs(i,(1<<(i-1)),i+1,small[i]),biao[i][++size[i]] = (1<<(i-1));
50     for(int i = 1 ; i <= tb ; ++i) dfs(i+ts,0,1,big[i]);
51     int end = (1<<ts)-1;
52     dp[end][1] = 1;
53     for(int i = 1 ; i <= tot ; ++i) {
54         for(int j = 0 ; j <= end ; ++j) {
55             if(dp[j][i]==0) continue;
56             dp[j][i+1] = dp[j][i];
57             for(int k = 1 ; k <= size[i] ; ++k)
58                 if((biao[i][k]&j)==biao[i][k]) dp[j-biao[i][k]][i+1] += dp[j][i];
59         }
60     }
61     printf("%lld",dp[0][tot]*2);
62 }
63 int main() {
64     freopen("test.in","r",stdin);
65     freopen("test.out","w",stdout);
66     scanf("%d",&n);
67     solve(n);
68 }

首先感觉那个DFS是可以直接做的,就是可以直接转移的,当时受了同学的蛊惑我于是打了个转移表。反正还是蛮优的,然后这道题重点就是DP了,最开始我只想考虑大质数的时候是可能有问题的。所以我把小质数加上来一起搞,可以处理出只选大质数的时候的方案。代码还是可以好好感受感受在最后一步J到大质数J+1的时候,我就可以知道集合s为各个状态时I的方案,然后就可以累加起来咯。

隔两天再看看,别忘了蛤蛤!

时间: 2024-11-07 14:01:25

2016_1_17_第二题的相关文章

2016/1/12 第一题 输出 i 出现次数 第二题 用for循环和if条件句去除字符串中空格 第三题不用endwith 实现尾端字符查询

1 import java.util.Scanner; 2 3 4 public class Number { 5 6 private static Object i; 7 8 /* 9 *第一题 mingrikejijavabu中字符“i” 出现了几次,并将结果输出*/ 10 public static void main(String[] args) { 11 12 String r ="imingrikejijavabi"; 13 14 15 //第一种 截取 16 int a=

最后一周第二天训练赛之第二题

试题: B - B Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ ICODER Description Mathews uses a brand new 16-bit instruction processor. (Yeah i am being sarcastic!). It has one register (say R) and it su

Learning Perl 第九章习题第二题

把输入文件中的所有Fred换成Larry, 不区分大小写. 知识点 1. 文本文件读写 2. 简单的正则替换 3. unless 的用法 4. $_ 的用法 Learning Perl 第九章习题第二题,布布扣,bubuko.com

2014百度之星资格赛第二题

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2560    Accepted Submission(s): 366 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.

NOIP2005-普及组复赛-第二题-校门外的树

题目描述 Description 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种有一棵树. 由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上还有多少棵树. 输入输出

第二题、第三题、第四题

1.以编程方式操作 HttpCachePolicy 类. HttpCachePolicy.SetExpires HttpCachePolicy.SetCacheability |NoCache|Private|Public|Server|ServerAndNoCache |ServerAndPrivate 2<%@ OutputCache Duration="60" VaryByParam="None" %>Duration 和 VaryByParam

05:统计单词数【NOIP2011复赛普及组第二题】

05:统计单词数 总时间限制:  1000ms 内存限制:  65536kB 描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置.注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样

LeetCode 第二题,Median of Two Sorted Arrays

题目再现 There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 题意解析 题目意思是给两个大小为m,n的有序数组(m,n可能为0),要求找出这两个数组的中位数.并且程序的时间复杂度必须不能超过O(log(m+n)). 这道题的

“金山杯2007逆向分析挑战赛”第一阶段第二题

注:题目来自于以下链接地址: http://www.pediy.com/kssd/ 目录:第13篇 论坛活动 \ 金山杯2007逆向分析挑战赛 \ 第一阶段 \ 第二题 \ 题目 \ [第一阶段 第二题] 题目描述: 己知是一个 PE 格式 EXE 文件,其三个(section)区块的数据文件依次如下:(详见附件)  _text,_rdata,_data 1. 将 _text, _rdata, _data合并成一个 EXE 文件,重建一个 PE 头,一些关键参数,如 EntryPoint,Imp