摘要:
题目: 动态规划版的硬币交换问题,求用最少的不同价值的硬币总数来换给出的硬币总数,如硬币只有1,6,10时,按贪心算法做就是先给价值为10的硬币,再给两枚价值为1的硬币,总硬币数为3,可是只需要两枚价值为6的硬币即可分析:用dp[i][j]来记录当前的硬币价值总数为j时需要的硬币最小数,i表示从硬币i到n的种类,j表示剩余的未交换的硬币价值总数,则状态转移方程为for(int j=0;j<=n;j++)dp[i][j] = j;dp[i][j] = dp[i+1][j] 当denom[i]>j时= min{dp[i+1][j],dp[i][j-denom[i]]+1}当j>= 阅读全文
摘要:
LCS最长公共子序列模板:状态转移方程为dp[i][j]=dp[i-1][j-1]+1 if(in[i]==target[i])=max{dp[i-1][j],dp[i][j-1]} else;void LCSLength(int m,int n,char *x,char *y,int **c,int **b){ int i,j;for (i = 1; i <= m; i++) c[i][0] = 0;for (i = 1; i <= n; i++) c[0][i] = 0;for (i = 1; i <= m; i++)for (j = 1; j <= n; j++) 阅读全文
摘要:
题目:A = {a1,a2...an}函数D(A) = A1+A2;A1 = {as1...at1}A2 = {as2...at2}1<=s1<=t1<=s2<=t2例子:A = {1 -1 2 2 3 -3 4 -4 5 -5}在这个例子中,选择{2,2,3,-3,4} 和 {5},得到答案。分析:最大子序列和,时间复杂度为O(n)int max = 0,current = 0;for(int i=0;i<n;i++){current+=a[i];if(current>max)max = current;if(current<0)current = 阅读全文
摘要:
题目:链 AGTGATGGTTAG可变形成AGTGAT-G-GT--TAG从而得到和最大分析:dp问题,属于最长公共子序列的变形题,用二维dp[i][j]存储当前串一的i位置和串二j位置上的和最大值,答案为dp[len1][len2],用地图map[i][j]存储AGCT的匹配程度,把输入的字符串用数组表示,并且a[i][j],b[i][j]与地图的对应更容易计算状态转移方程为dp[i][j]=max{dp[i][j],dp[i][j-1]+map[a[i]][5],dp[i-1][j]+map[5][b[j]],dp[i-1][j-1]+map[a[i]][b[j]]}#include &l 阅读全文
摘要:
题目:岛上的居民要修最短的路来使得费用最少分析:实际上是求最小生成树,可以用prim算法和kruskal算法,基于刚学kruskal算法,以下是用kruskal算法做的。kruskal算法的思想是:先把所有的边按照非降序排列,从而观察每条边是否能与以前的边组成环,能的话就不选,不能的话就选择,而判断是否组成环路的话可以通过使用并查集实现并查集的思想是:{1,2,3},{4,5},{6,7,8},{9},当该边是当前最少的边时,两端顶点为1,4,因为1,4在两个不同的集合中,故而不能组成回路,假设在同一集合中,如1和2,因为前面肯定1,2,3能直接或间接相连接,加入边(1,2)可定能使该图组成环 阅读全文
摘要:
题目:三维迷宫题:分析:在二维迷宫上多了上下搜索,求最优解,用BFS做,用队列储存上一个搜索过的节点,在下一次搜索时把删除最先入队的那个就行,另外得储存上一次的坐标,可以直接把x,y,z坐标分别乘以10000,100,1就行(注意到数据不超过30),把它作为新元素加入到队首中,借助数组判断是否已经走过,可以节省大量时间#include <iostream>#include <cstring>#include <queue>#include <string>#include <cstdio>using namespace std;#de 阅读全文
摘要:
题目:有s个satellite channels,但有p(p>s)个地方,若任意两个地方有satellite channels,则无视该距离,并且剩余的地方只能与其他地方通过无线电连接,需要距离,且需要的距离只与最大距离有关,问该最大距离的最小值(大概是这样啦)分析:实际上就是求最小生成树中的第p-s大的数,可以先通过prim算法生成最小生成树,然后通过对生成树中的边进行快速排序,得到第p-s大的数#include <iostream>#include <cstring>#include <cstdio>#include <algorithm&g 阅读全文
摘要:
题目大意就是给出一个不超过2^31的数,来判断它是否为素数,对于此题的规模,一般的素性检测显然不行,要用到Miller rabin, 这个算法主要是基于费尔马小定理,如果 n 为素数,那么对于小于n的数a有a^(n-1) = 1(mod n) ('='在这里就代表同余符号)。显然这是一个必要条件,然而只要满足这个条件就基本上是一个素数了,称为‘伪素数’,正确率为1-(1/4)^m,m用不同的基测试的次数,所以多测试几次就可以保证结果的正确了#include <iostream>#include <cstdlib>#include <cstdio&g 阅读全文
摘要:
题目:每次每一位上只能该位变一个数字,并且组成一个新的素数,问最少能用多少次变成第二个给出的素数分析:既然归类到了BFS,可以用BFS来做,可先生成一个素数判断表,加快判断,然后枚举每一位上的数,给以往的BFS一样,只不过每次要计算0到9而已(注意:千位上不能为0,个位上是偶数的话就不用考虑了)#include <iostream>#include <cstring>#include <queue>using namespace std;int m,n,ans;int a[6];bool isprime[10000],use[10000];void make 阅读全文
摘要:
最长公共子序列状态转移方程为dp[i][j] = dp[i-1][j-1]+1 s1[i]==s[j]= max{dp[i-1][j],dp[i][j-1]} s1[i]!=s2[j]#include <iostream>#include <cstring>#include <string>using namespace std;#define X 255int dp[X][X];string s1,s2;int main(){freopen("sum.in","r",stdin);freopen("sum. 阅读全文