NOIP 2001 提高组 题解

No 1. 一元三次方程求解

https://vijos.org/p/1116

看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~

数据小 暴力枚举即可

 1 double a,b,c,d;
 2 double x;
 3
 4 int main()
 5 {
 6     ios_base::sync_with_stdio(0);
 7
 8     cin>>a>>b>>c>>d;
 9
10     for(double i=-10000;i<=10000;i+=1)
11     {
12         x=i/100;
13
14         if(abs(a*x*x*x+b*x*x+c*x+d)<0.01)
15         {
16             printf("%.2f ",x);
17         }
18     }
19
20     return 0;
21 }

No 2. 数的划分

https://vijos.org/p/1117

dp/dfs

dp

用f(i,j)表示i这个数分成k份有多少种分法

毫无疑问

f[i][j]=f[i-1][j-1]+f[i-j][j];

因为 f(i,j) 可以从 f(i-1,j-1)推出

又要保持不下降的分划

所以可以从f(i-j,j)推出
 1 int n,k;
 2 int f[222][222];
 3
 4 void init()
 5 {
 6     cin>>n>>k;
 7
 8     for(int i=1;i<=n;i++)
 9     {
10         for(int j=1;j<=i;j++)
11         {
12             f[i][j]=inf;
13         }
14     }
15
16     for(int i=1;i<=n;i++)
17     {
18         f[i][1]=1;
19     }
20 }
21
22 int main()
23 {
24     init();
25
26     for(int i=2;i<=n;i++)
27     {
28         for(int j=2;j<=i;j++)
29         {
30             f[i][j]=f[i-1][j-1]+f[i-j][j];
31         }
32     }
33
34     cout<<f[n][k]<<endl;
35
36     return 0;
37 }

dfs

暴力枚举

只要不下降+剪枝就可以了

 1 int n,k;
 2 int ans;
 3
 4 void dfs(int nw,int sum,int num)
 5 {
 6     if(num==k)
 7     {
 8         if(sum==n)
 9         {
10             ans++;
11         }
12         else
13         {
14             return;
15         }
16     }
17
18     if(sum==n)
19     {
20         return;
21     }
22
23     for(int i=nw;i<=n-sum;i++)
24     {
25         dfs(i,sum+i,num+1);
26     }
27
28     return;
29 }
30
31 int main()
32 {
33     ios_base::sync_with_stdio(0);
34
35     cin>>n>>k;
36
37     for(int i=1;i<=n/2;i++)
38     {
39         dfs(i,i,1);
40     }
41
42     cout<<ans<<endl;
43
44     return 0;
45 }

No 3. 统计单词个数

https://vijos.org/p/1118

dp

这几年dp考的好多啊

这题题解我真的不会写 我的写法我自己都看不懂

复制一段

划分这个DP,很基础。

然后,是sum[i][j],第i个字母到第j个字母一共可以形成多少个单词,ccy也用的Dp。

sum[i][j]=sum[i][-1]+(包含可以添加最后一个字母j的单词的总个数)。

ccy,WA在……比如现在可以添加一个新单词,k到j,但是,若果以k为起点,在sum[i][j-1]中已经有过单词,该新单词就不添加。于是乎,ccy光荣地WA掉一个点,因为,

那个点有两个相同的单词,我就扩展了两次。

 1 string s;
 2 int slen;
 3 string words[maxm];
 4 int wordslen[maxm];
 5 int f[maxn][maxm];
 6 int sum[maxn][maxn];
 7 int n,k,m;
 8
 9 void init()
10 {
11     string tmp;
12     cin>>n>>k;
13     for (int i=1;i<=n;i++)
14     {
15         cin>>tmp;
16         s+=tmp;
17     }
18     slen=s.size();
19     cin>>m;
20     for (int i=1;i<=m;i++)
21     {
22         cin>>words[i];
23         wordslen[i]=words[i].size();
24     }
25 }
26
27 int add(int l,int r)
28 {
29     int ans=0;
30     if (r-1>=0) ans=sum[l][r-1];
31     bool vis[maxn]={0};
32     for (int i=1;i<=m;i++)
33     {
34         int qd=r-wordslen[i]+1;
35         if (qd<l) continue;
36         if (qd==s.find(words[i],qd))
37         {
38             if (vis[qd]) continue;
39             vis[qd]=1;
40             ans++;
41             for (int j=1;j<=m;j++)
42             {
43                 int dq=r-wordslen[j];
44                 if (dq==qd)
45                     if (dq==s.find(words[j],dq))
46                     {
47                         ans--;
48                         break;
49                     }
50             }
51         }
52     }
53     return ans;
54 }
55
56 void gsum()
57 {
58     for (int i=0;i<=slen-1;i++)
59         for (int j=i;j<=slen-1;j++)
60         {
61             sum[i][j]=add(i,j);
62         }
63 }
64
65 void work()
66 {
67     for (int i=0;i<=slen-2;i++)
68         f[i][1]=sum[0][i];
69     for (int i=0;i<=slen-2;i++)
70         for (int j=2;j<=min(k-1,i+1);j++)
71             for (int u=j-2;u<=i-1;u++)
72                 f[i][j]=max(f[i][j],f[u][j-1]+sum[u+1][i]);
73     int ans=0;
74     if (k==0)
75         ans=sum[0][slen-1];
76     else
77         for (int i=k-1;i<=slen-2;i++)
78             ans=max(ans,f[i][k-1]+sum[i+1][slen-1]);
79     printf("%d\n",ans);
80 }
81
82 int main()
83 {
84     int qn;
85     qn=1;
86     while(qn--)
87     {
88         init();
89         gsum();
90         work();
91     }
92
93     return 0;
94 }

先写这么多 第四题下午再写

Bye~~~

时间: 2024-10-17 18:37:59

NOIP 2001 提高组 题解的相关文章

NOIP 2014 提高组 题解

NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法,直接模拟,别读错题. 1 int wn[5][5]={{2,0,1,1,0}, 2 {1,2,0,1,0}, 3 {0,1,2,0,1}, 4 {0,0,1,2,1}, 5 {1,1,0,0,2}}; 6 7 int n,na,nb; 8 int a[222],b[222]; 9 int s1,s

NOIP 2008提高组第三题题解by rLq

啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊

noip2001提高组题解

今天继续感动滚粗.第一次提交170分,不能多说. 第一题:一元三次方程 明明是寒假讲分治的时候做过的题居然还是WA而且只拿了60分,说明知识掌握实在不够牢固. 寒假做的是保留4位小数,原题只保留2位,又因为答案在[-100,100],所以直接枚举-10000到10000即可. 然后鉴于寒假的时候写的二分,我就傻X兮兮地在循环里面写了个二分...尼玛经验害死人啊...更可怕的是题目的hint里也明显地提示了二分...然后我就逗比了. 提交4次AC . 第二题:数的划分 去年学回溯的时候就做过,所以

noip2004提高组题解

这次有两道题以前已经做过了,所以分数什么的也没有意义了.发现这年的难度设置极不靠谱,前三题都比较简单,最后一题太难,不知道出题人怎么想的. 第一题:储蓄计划 模拟. 第二题:合并果子 贪心.每次选最小的两堆合并. 第三题:合唱队形 两次动规.题目可以转化为找出一个人,使得以他为尾的最长上升子序列的长度最大,并且以他为首的最长下降子序列的长度也最大. 第四题:虫食算 马上想到搜索.但是规模太大,N可能有26位,如果简单枚举那么运算次数是26!≍4e27:剪枝方面只想到一个很弱的剪枝(对于26的规模

noip2003提高组题解

这一年的前三题虽然难度不高,但是第二题极为繁琐,想在考场上用较短的时间拿到第二题的分数难上加难.所以必须要调整策略,争取拿其他三题的分数.第四题是比较普通的搜索题,分数比较好拿,但是很容易想成树形DP,就只能拿30~50分. ? 第一题:神经网络 模拟 有几个注意点: 输入层(即第一层)的结点的U(阈值)是没有用的: 题目说输出「最后状态非零的输出层神经元状态」,但实际上输出的是状态大于0的值. 由于没有注意到神经元只有在兴奋状态时才会向下传送信号,所以WA了1次. ? 第二题:侦探推理 模拟+

NOIP 2012 提高组 DAY1 T2 国王游戏

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

noip2000提高组题解

事实再次向我证明了RP的重要性... 第一题:进制转换 是我最没有把握AC的一道题目却是我唯一一道AC的题目,真是讽刺.看完题目几乎完全没有往正常的解法(取余倒序)去想,直接写了搜索,因为数据范围在2^16,感觉枚举每一位上的数应该就够了,但是在自己的电脑上连样例都用了3.4s,然后想不到任何有效的剪枝,就果断放弃了.最后写完其他三题之后还是回过头看了下这道题,还是没往正常的解法想....结果惊人地AC了...RP真的太重要了. 然后经提醒终于想到了正常一点的解法,查了网上的题解之后开始自己写取

noip2010提高组题解

NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n的棋盘,每个格子对应一个分数,1,2,3,4的卡片共m张,给出四种卡片各自的数量,求改变出牌顺序能获得的最大分数. 思路:开了一个四维的f[i][j][k][l]来表示每张牌有了几张时的最大分数: F[i][j][k][l]=max(f[i-1][j][k][l],f[i][j-1][k][l],f

NOIP2007 提高组 题解

2007 提高组题解 第一题 一开始还想是不是要用哈希表储存呢,但仔细想了一会儿,那个数据量20W 用个快排序,时间是能过的.所以这道题用个STL的快排,再一个循环统计个数就OK了.但最后交上去评测时0分,很尴尬.就是我在数据初始化时从一开始计数,我循环又从一开始,你懂的,多算了一次,爆掉了.改了就100了.200W的话数据就很强了,用哈希好一些. 第二题 额,写得很快,果然这种无脑模拟题最适合我了.但自信没检查,带了3组给的数据就走了.果然错了,过了4个点好像.主要是题没读完,没有判断处于字母