51nod
文章平均质量分 53
但求-_-心安
充满鲜花的世界到底在那里,如果他真的存在那么我一定会去。
展开
-
51nod 1649 齐头并进 (最短路)
求两次最短路,1到n#include using namespace std;int a[405][405],path[405],vis[405];int main(){int n,m,x,y;scanf("%d%d",&n,&m);memset(a,0,sizeof(a));for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y);原创 2017-11-22 21:29:01 · 291 阅读 · 0 评论 -
51nod 1115 最大M子段和 V3 (链表)
这个题就是最大M子段和 V2的稍微改改就能过了,两个改动,1:如果首位相同首尾相同,首尾合并。2:把首尾接起来本来就是一个链表,让这个链表首尾相连。每一次搜索是log(k)一共k-m次。k是整数序列的集合。#include #include #include #include #include #include #include #include #include using原创 2017-10-05 10:43:14 · 423 阅读 · 0 评论 -
51nod 1052 最大M子段和 (区间dp)
看到大佬题解,感觉很全面动态规划,借助矩阵可以直观的看到计算过程。定义二维数组dp, dp[ i ][ j ],表示前 j 项所构成 i 子段的最大和,且必须包含着第j项,即以第j项结尾然后是一个递推过程。求dp[ i ][ j ],有两种情况1、dp[ i ][ j ] = dp[ i ] [ j-1 ] + a[ j ] ,即把第j项融合原创 2017-10-04 21:02:54 · 400 阅读 · 0 评论 -
51nod 1057 N的阶乘 (水题ing……)
#includeusing namespace std;const int maxn=1e8;int main(){int n;long long a[10000];scanf("%d",&n);int m=0;a[0]=1;for(int i=1;i<=n;i++){ int c=0; for(int j=0;j<=m;j++) {原创 2017-10-19 20:00:34 · 354 阅读 · 0 评论 -
51nod 1065 最小正子段和
因为看错一个正数,我把0算上了,改了无数次,GG#include #define ll long longusing namespace std;long long a[50010],x,min1=1e18;sets;int main(){ int n; scanf("%d",&n); a[0]=0; for(int i=1;i<=n;i++) {sc原创 2017-10-03 18:36:03 · 254 阅读 · 0 评论 -
51nod 1056 最长等差数列 V2
这个和1055那个题差不多,稍微改改就过了,首先是剪枝的改写,这个剪枝是必过的,唐老师在讨论里进行了证明。首先要明确等差数列的定义。一个等差数列可以用首项、公差和项数的三元组 (first,delta,length) 表示,当然这个 first 也可以换成末项 last ,取决于你的算法。我们要考虑的等差数列要尽量用少的信息表示所有的可能,也就是说提取出来的等差数列之间不能原创 2017-10-03 16:51:34 · 434 阅读 · 0 评论 -
51nod 1181 质数中的质数(质数筛法)
质数筛法#include using namespace std;typedef long long ll;const int N=1e6+10000;int vis[N]={0},prime[N],prime1[N],cnt=0,cnt1=0;void init(){ for(int i=2;i<N;i++) { if(vis[i]==0)原创 2017-10-10 17:33:07 · 194 阅读 · 0 评论 -
51nod 1055 最长等差数列
n^2的算法可以做,先给数组a进行排序,遍历a【i】,让j=i-1,k=i+1.if(a[j]+a[k]>a[i])j--if(a[j]+a[k]41 2 3 4这组测试数据看着代码想想就可以了。#include #include#define ll long longusing namespace std;int a[10010];short i原创 2017-10-03 15:21:59 · 209 阅读 · 0 评论 -
51nod 1183 编辑距离
开始不知道怎么想的想偏了。。。很简单的三种情况,第一个字符串+1,第二个字符串+1,两个相同的情况dp不能想太多,想出,这个数怎么由前面的状态转移而成就行了。想的多,要背锅。#include #include#define ll long longusing namespace std;char s[2][1500];int dp[1500][1100];int main(原创 2017-10-03 11:59:38 · 162 阅读 · 0 评论 -
51nod 1053 最大M子段和 V2 (链表 对经典dp进行优化)
把所有连续正数或者负数整合起来。比如 1 2 3 -1 -2 6 整合后是6 -3 6.这样用set存储他们的绝对值。每次让绝对值最小的和两边的进行整合。每次整合肯定会少一个正数。比如当前绝对值最小的是负数,把周围两个正数和这个负数进行合并。形成一个正数。把这三个去掉,入队新的这个正数。如果最小的为正数,正好把正数和周围的负数合并。少一个正数。最后剩下m个最大的正数序列就行了。每次少那个用所有正数原创 2017-10-05 10:48:19 · 458 阅读 · 0 评论 -
51nod 1573 美丽的集合(bitset)
正如题解所说,这个可以暴力,但是必须用bitset,因为这个是lg(n)的算法。所以我直接暴力错了几组测试数据拿了5分。。。心痛,只用过一次bitset,然而当时想到了这个,并不熟练也不知道他的复杂度怎么来的。#include#include#include using namespace std;const int N=1005;bitset a[N],b;int n,i,f[N原创 2017-10-06 11:22:02 · 385 阅读 · 0 评论 -
51nod 1058 N的阶乘的长度
还有这个公式?1*2*3*4的位数为log10(1)+log10(2)+log10(3)+log10(4),转化为整形再加上 1#include using namespace std;int main(){double n;scanf("%lf",&n);double ans=0;for(int i=1;i<=n;i++) ans+=log10(i);int k=a原创 2017-10-12 19:24:25 · 220 阅读 · 0 评论 -
51nod 1770 数数字
这种简单的套路题只有想到想不到。。#include #include #include using namespace std;int main(){int t;scanf("%d",&t);while(t--){ int a,b,n,d; scanf("%d%d%d%d",&a,&b,&d,&n); int c=a*b; if(n==1&&原创 2017-12-09 16:33:43 · 201 阅读 · 0 评论 -
51nod 1833 环 (dp)
虽然标题是图论,我感觉和图论有关系,但是和dp关系更密切。我们发现这个不相交环其实就是把原图造成二分图的一个完全匹配。比如如果有一个i->j的边我们就在i->j'的二分图中建一个边。我们可以容易知道二分图的完全匹配就是不相交环覆盖的方案数。那么就可以用集合dp在O(n2^n)中找出所有完全匹配就可以了。就是枚举一下这个集合然后找一个固定元素出来求一下贡献就可原创 2017-11-03 14:47:33 · 847 阅读 · 2 评论 -
51nod 1621 花钱买车牌
水水的题,做了很长时间才出来,还看了两组数据,抠脚了,很皮,思路是变为k个0,k个1.。。。k个9,变得话从 t左右减相同的这样最小,看哪个最小,输出哪个,还有就是顺序问题,顺序的话如果有相等的数字,比较改变后字符串大小,没有相等的如果把大的数改成小的数从前往后改,小的数改为大的数,从后往前改。。。。。必须要细节。。。#include #include using namespace原创 2017-11-03 17:43:35 · 545 阅读 · 0 评论 -
51nod 1003 阶乘后面0的数量
求2和5的个数,一共多少个5 求出N的阶乘的所有因式(1,2,3,...,N)分解中5的指数。然后求和,比如25是5*5所以#include #include #include #include using namespace std;int mod=1e8;int main(){long long sum=1;int ans=0;for(int i=2;i<=300;原创 2017-11-17 12:33:38 · 280 阅读 · 0 评论 -
51nod 1829 函数
flag既然立上了,今天时间不算少,如果坏了规矩,以后就没法搞了,所以,最后一题。题意有点难理解,容斥原理。#include#define LL long longusing namespace std;const int maxn=1000005,tt=1e9+7;LL ji[maxn],ans=0;int n,m,p;LL qsm(LL w,int b){ LL n原创 2017-11-02 21:58:25 · 264 阅读 · 0 评论 -
51nod 1791 合法括号子段 (队列)
每次匹配上一个,当前位置能匹配的括号数应该是左括号减一位置的括号数+1;代码一看就懂,还自带stack函数,省的数组模拟了。#include using namespace std;char s[1100009];long long num[1100009];stackq;int main(){ int t; scanf("%d",&t); while(原创 2017-11-02 21:56:42 · 346 阅读 · 0 评论 -
51nod 1836 战忽局的手段
看了这个题的题解是真心佩服,学到了一招,之前对矩阵快速幂也只是知道,现在明仔了他的用法用在那里,这个题解是真的厉害,推导的完全虐到我这大学生(渣渣),局座果然强,能忽悠。令f[i][j]为i次忽悠中有j个事件的概率显然f[i][j]=f[i-1][j]*j/n+f[i-1][j-1]*(n-j+1)/n令g[i]为i次忽悠之后期望的事件数我们考虑这个g[i]=(n-1)/n*g原创 2017-11-02 21:18:34 · 223 阅读 · 0 评论 -
51nod 1424 零树(树dp)
dp【u】【0】代表根节点需要减的数,dp【u】【1】代表根节点需要加的数。#include using namespace std;const int maxn=1e5+5;vectora[maxn];long long dp[maxn][2];int v[maxn];void dfs(int u,int fa){ for(int i=0;i<a[u].size();i原创 2017-10-14 11:39:44 · 330 阅读 · 0 评论 -
51nod 1042 数字0-9的数量
给出一段区间a-b,统计这个区间内0-9出现的次数。比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。Input两个数a,b(1 Output输出共10行,分别是0-9出现的次数Input示例10 19Output示例1111111原创 2017-10-03 10:22:59 · 337 阅读 · 0 评论 -
51nod 1050 循环数组最大子段和
就是三种状态想出来就行了,开始想出来两种,看了一组测试数据想了一种。1.正常的最大连续序列2.开始在尾,结束的首第一种正常求,第二种考虑答案的组成,开始的一段+到结尾的一段,那么中间为什么去掉呢,因为中间那段和为负数,只要求出负数最大的连续子序列去掉就行了max(ans1,sum+ans2);中间那段挖空了,所以首尾要接起来,总和减去那段负数的最大连续字段就行了,#includeu原创 2017-10-02 18:04:39 · 202 阅读 · 0 评论 -
51nod 1270 数组的最大代价
a数组的每个值取1或者b[i],所以dp【2】【maxn】就可以了#include using namespace std;int n;int a[50005];int dp[2][5005];int main(){scanf("%d",&n);scanf("%d",&a[1]);dp[1][0]=0;dp[0][1]=0;for(int i=2;i<=n;i++)原创 2017-09-03 11:19:30 · 210 阅读 · 0 评论 -
51nod 1732 51nod婚姻介绍所
气死了,c++提交就超时,把#include换成了#include就过了。。。。气死了,我还优化了半小时。。。。你告诉我换个头文件用c语言提交?#include int n;int dp[1005][1005];char s[1005];void init(){ //memset(dp,0,sizeof(dp)); dp[0][0]=n; for(int i=n-1;i原创 2017-09-03 10:43:01 · 201 阅读 · 0 评论 -
51nod 1043 幸运号码 (数位dp)
dp[i][j]表示 i 个数和为 j 的总数(包含0开头情况)dp[i][j] = dp[i-1][j-k]i & 1 :这里用滚动数组节省内存非0开头的情况 * 0开头的情况:(dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i],最后将其累加即为结果。开始没有想到这么做,还傻傻的dfs,用dp[1000][10]记录,今天心情不好,超级原创 2017-09-02 20:06:43 · 322 阅读 · 0 评论 -
51Nod-1412-AVL树的种类(树形dp)
状态转移方程1、dp[i][k] += dp[i - 1 - j][k - 1] * dp[j][k - 1] 2、dp[i][k] += 2 * dp[i - 1 - j][k - 2] * dp[j][k - 1]51nod评测机是window系统,要用%I64d#includeusing namespace std;typedef long long ll;#def原创 2017-09-02 17:57:58 · 278 阅读 · 0 评论 -
51nod 1134 最长递增子序列
二分加dp#includeusing namespace std;typedef long long ll;#define pb push_backint INF=1e9+7;const int mod=1e9+7;int n,m;int x;int g[50005];int main(){scanf("%d",&n);int ans=1;for(int i=1;i<=原创 2017-08-31 21:02:04 · 199 阅读 · 0 评论 -
51 nod 猪和回文
遍历从i,j到x,y,i和j代表从中间出发到0 0,x,y是从中间出发到n,m,如果遍历的话是n^4,y可以用x算出来,所以遍历n^3就够了,但是数组开不下,用滚动数组。3维循环,#includeusing namespace std;typedef long long ll;#define pb push_backconst int mod=1e9+7;int n,m;int d原创 2017-08-31 19:56:15 · 277 阅读 · 0 评论 -
51 nod 1051 最大子矩阵和
这个题 如果超级暴力做,起点i,j 终点p,q暴力循环的话大概是n^4所以要进行一些优化,优化掉一维数组,a[i][j]代表的是j这一列中前i个数的和,这样就可以少一重对列的循环。和那个最大连续子串有点像。#includeusing namespace std;typedef long long ll;#define pb push_backconst int maxn=5原创 2017-08-31 17:51:52 · 234 阅读 · 0 评论 -
51nod 1021 石子归并(区间dp 详细解释)
区间dp模板题,好长时间没做过区间dp了,当初学的一点知识也忘得没有了,区间dp从小的区间,慢慢成大的区间,以2为区间,然后以3为区间……以3为区间就可以用到以2为区间,两堆石子合并,就是把这两堆石子的数量加一次,把i——j的石子合并,就是把i——j区间内的石子加一次,他们必须是连着的才能合并,如果区间为3,肯定是区间为2的和区间为1 的合并了一次,所以,区间为3的取他们的最小值就行了举个例子原创 2017-09-07 18:18:36 · 376 阅读 · 0 评论 -
51nod 1086 背包问题V2 (巧妙dp,二进制)
这里可以用多重背包拆成01背包求解的思想,不过在拆的时候不能将Cn拆成1+1+1+1+1+1.....+1的形式。这么做会超时。应该将Cn拆成 Cn=1+2+4+8+...+(Cn-sum)。 如果能理解完全背包就能理解这个,完全背包将Cn拆成1+1+1+1+1+1.....+1的形式的时候是每次放一个a【i】包,或者不放。最多就是cn,拆分成1+2+4+8+...+(Cn-su原创 2017-09-03 13:41:42 · 231 阅读 · 0 评论 -
51nod 1202 子序列个数(字符串计数)
dp[i]代表是以i位的a[i]结尾,有多少种,(包括空集)状态转移方程 1.如果a[i]之前没有出现过dp[i]=2*dp[i-1] 前面i-1有dp[i-1]种可能,第i个数放或不放 2.如果a[i]之前出现过:dp[i]=2*dp[i-1]-dp[mark[a[i]]-1] 减去重复的部分,mark【i】是a[i]最近一次原创 2017-09-03 16:49:44 · 583 阅读 · 0 评论 -
Codeforces Round #439 (Div. 2) E. The Untended Antiquity (hash+数状数组)
这个题,做出来的人很多,我感觉是数据不够强,我看了很多人的代码直接暴力也能过了,直接暴力如果数据够强的话肯定是时间超限,边缘数据不够强。如果和上次一样估计很多人的E会GG。我看到一位OIdalao的代码,认为这个是正确的解法,对每一道围墙进行hash处理,然后用二维的树状数组来解决这个问题。感觉博主已经写得简单易懂了。长了姿势#includeusing namespace std;type原创 2017-10-07 12:50:07 · 318 阅读 · 0 评论 -
51nod 1007 正整数分组(背包)
将一堆正整数分为2组,要求2组的和相差最小。例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的。Input第1行:一个数N,N为正整数的数量。第2 - N+1行,N个正整数。(N Output输出这个最小差Input示例512345Output示例1原创 2017-10-02 17:20:07 · 247 阅读 · 0 评论 -
51nod 1009 数字1的数量
给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。Input输入N(1 Output输出包含1的个数Input示例12Output示例5相关问题解题思路:原创 2017-10-02 16:26:02 · 221 阅读 · 0 评论 -
51nod 1837 砝码称重
原地址:http://blog.csdn.net/qq_28954601/article/details/78151199最坏情况就是每次称量的结果都和把 ai 当作 i 称量的结果相同,所以只用考虑在这种情况下要多少次称量才能称量出至少一定有一个 ai=i 。显然答案不会超过 3 ,因为高斯证明过任意一个正整数可以表示成三个三角形数的和。实际上答案最大是 2 ,通过观察或原创 2017-10-02 15:54:53 · 310 阅读 · 0 评论 -
51nod 1256 乘法逆元
费马小定理,我好像一开始只看了皮毛,只看了简单的乘法逆元,因为一般的都是x^p=x(mod p)p是素数。如果p不是素数应该怎么办?欧拉定理可以解决这个问题,假设m=p1^e1*p2^e2...pn^en.x^h(m)=1(mod p).数学符号打不出来,想看详细的去百度吧。#include using namespace std;long long n,m;long long eule原创 2017-10-10 11:20:56 · 209 阅读 · 0 评论 -
51nod 1019 逆序数 (归并排序)
归并排序的复杂度是n*log(n)和快排的差不多。每次要去排序的是前半部分和后半部分,前半部分是排好序的,后半部分也是排好序的。当左边的子序列出现一个数大于右边的子序列的时候,左边子序列末尾数的位置减去当前左边这个数的位置加1就得到了有多少逆序对了#include using namespace std;const int maxn=5e4+7;int ans=0;void merge原创 2017-10-08 19:13:44 · 270 阅读 · 0 评论 -
51nod 1294 修改数组(dp,逆向思维,最大上升子序列)
------------------------------------看别人的代码写得题解---------------------------------------这个题和那个最大上升子序列很像,就是不是严格递增的最大上升自序列。首先应该去想如果a[i]-i小于0,必须要改,因为这个是按照严格的递增来排列的。剩下的就要找不是严格递增的最大上升自序列。用n-最大上升自序列,就是答案。如原创 2017-10-07 20:17:54 · 302 阅读 · 0 评论 -
51nod 1354 选数字 (01背包变形)
dp5级题,是一个背包的变形题,我想把它放在五级题的原因就是很难想到这只是一个背包题吧。用map处理一下,和离散化的作用是一样的。只是用了系统自带的函数库而已。#include #define ll long longusing namespace std;const int maxn=1010,mod=1e9+7;int a[maxn];maptemp1,temp2;map::i原创 2017-10-07 19:44:43 · 257 阅读 · 0 评论