摘要:简单dp。代码:#include<iostream>#include<fstream>using namespace std;int n,m,r;struct e{ int s,t,f;};e a[1001];int cmp(const void *a,const void *b){ return (*(e *)a).s-(*(e *)b).s;}int dp[1001];void read(){// ifstream cin("in.txt"); int i,j,k; cin>>n>>m>>r; n=m; for
阅读全文
摘要:01背包的变形。代码:#include<iostream>#include<fstream>using namespace std;int dp[20000001];int n,h;int a[21];void read(){// ifstream cin("in.txt"); int i,j,k=0; cin>>n>>h; for(i=1;i<=n;i++) { cin>>a[i]; k+=a[i]; } for(j=1;j<=a[1];j++) dp[j]=a[1]; for(j=a[1]+1;j&
阅读全文
摘要:不降子序列。代码:#include<iostream>#include<fstream>using namespace std;int a[30001];int n;int b[30001];int find(int s,int value){ int i=0,k; while(i<=s) { k=(i+s)>>1; if(b[k]>value) s=k-1; else i=k+1; } return s;}void read(){// ifstream cin("in.txt"); int i,j,k,m,m1; cin&g
阅读全文
摘要:递增或递减序列。代码:#include<iostream>#include<fstream>using namespace std;int a[30001];int n;int b[30001];int c[30001];int find(int s,int value){ int i=0,k; while(i<=s) { k=(i+s)>>1; if(b[k]<value) s=k-1; else i=k+1; } return s;}int find1(int s,int value){ int i=0,k; while(i<=s) {
阅读全文
摘要:偏序定理。注意1. 偏序定理。2. 最长递减子序列的nlogn算法。3.qosrt是不稳定排序。代码:#include<iostream>#include<fstream>using namespace std;struct e{ int w,h;};e a[20001];int n;int b[20001];int cmp(const void *a,const void *b){ if(((e *)b)->w-((e*)a)->w!=0) return ((e *)a)->w-((e*)b)->w; else return ((e*)b)-&
阅读全文
摘要:水题。o(n^2)也可以。代码:#include<iostream>#include<fstream>using namespace std;int a[10001];int b[10001];int n;void read(){// ifstream cin("in.txt"); int i,j,k; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n;i++) b[i]=1; for(i=1;i<=n;i++) for(j=i-1;j>=0;j--)
阅读全文
摘要:dp题,神奇的替换:ONE 匹配一个单词ZERO_ONE 匹配零个或一个单词ANY 可以匹配零个或多个单词这样:* = ONE, ANY? = ONE, ZERO_ONE, ZERO_ONE! = ONE, ONE, ONE, ANY替换后即可dp。注意这个例子:a.b.?!.c (输出yes)代码:#include<iostream>#include<fstream>using namespace std;char c[400][300],c1[400][300];int n1,n2;char c2[120000];int n;bool dp[400][400];vo
阅读全文
摘要:题意:给定n根长度的木棍,求围成的三角形中面积最大的那个。找好状态就好办。dp[i][j][k]=dp[i-1][j][k]||dp[i][j-a[i]][k]||dp[i][j][k-a[i]];dp[i][j][k]表示前i跟木棒可构成长度j,与长度k。代码:#include<iostream>#include<fstream>#include<cmath>using namespace std;int n;int a[41];bool dp[41][1000][1000];int sum=0;int ok(int s,int t,int k){ dou
阅读全文
摘要:题意:求解码方案个数。注意细节。如10,20只有一种解码方案,22有两种。代码:#include<iostream>#include<fstream>using namespace std;long long dp[1000001];int n;void read(){// ifstream cin("in.txt"); int i,j,k; char c[1000001]; while(1){ cin>>c; n=strlen(c); if(strcmp(c,"0")==0) return; memset(dp,0,
阅读全文
摘要:少人做的水题。直接模拟即可,不算dp题。代码:#include<iostream>#include<fstream>using namespace std;int a[10001][7];int n;int ok(int s,int t){ int i=0; if(t==1) { i=max(a[s][2],i); i=max(a[s][3],i); i=max(a[s][4],i); i=max(a[s][5],i); } else if(t==2){ i=max(a[s][1],i); i=max(a[s][3],i); i=max(a[s][6],i); i=ma
阅读全文
摘要:题意:要买若干种价值的珍珠,但买某种珍珠必须多付10颗此种珍珠的价钱,及如果买价值为1的珍珠100颗,必须付的钱数为110。一颗珍珠可以用比它贵的珍珠充数,因此买多种珍珠的时候用贵的代替便宜的可能更省钱。例如买100颗价值为2的、1颗价值为1的,此时买101颗价值为2的为较优方案。输入要买的若干种珍珠,可用高价珍珠充数的条件下,问最少需要花费多少钱。经典dp:高档次的珍珠若要和低档次的珍珠合并,那么这些低档次的珍珠必须是和它紧邻的,也就是说,它只有和第i-1,i―2,…,i-j 类珍珠合并,同时这种合并必须是连续的。用sum[i] 记录前 i 类珍珠的总数。推出状态转移方程:dp[i] = m
阅读全文
摘要:题意:题目大意是说n个人做m项工程,然后给出工人的薪水,和工程按期完工的概率,以及按时完工的酬劳和未按时完工的罚款,要求出最大利润。。需要注意的是,薪水输出的是欧元为单位,输出的是以分为单位。(number是数量的意思,也即给出的是若干个人做同一个工程完工的概率)刚开始题意理解错了,咳。dp[i][j]=dp[i-1][j-k]+cost[i][k];dp[i][j]表示i个工程用j个人的最大收益。(注意搭配dp[i][j]可能为负数,因此wa一次)#include<iostream>#include<fstream>using namespace std;int m,
阅读全文
摘要:题意在一组数中选择若干个数的情况。有20个数:1 1 1 2 2 2 2 3 3 4 4 4 4 4 4 5 6 7 8 9选2只有有40种情况当开始想错了,咳!#include<iostream>#include<fstream>using namespace std;int n,m;long long dp[51][51];int num[51];void read(){// ifstream cin("in.txt"); int i,j,k; int K; int ans=0; while(1) { cin>>n>>m;
阅读全文
摘要:题意:有两个元素个数都为N的集合,要交换N/2个元素,但有些元素不能在一起,求最多能交换多少元素?1号监狱的某a个人和2号监狱的某b个人是被“绑定”的,即这a个人中的任何一个人都不能和那b个人中任何一个人在同一监狱。比如:1号监狱的5号犯人和2号监狱的8号9号不能在一起,2号监狱的8不能和1中的2,2号监狱的9不能和1的3,那么1中的2 3 5与2中的8 9被“绑定”,必须同生共死!这样把数据分成若干组,接下来就可以DP了:现在问题转化为:有p对儿数a[i],b[i],1<=i<=p,选出一些对儿,使SUMa == SUMb并且sum<=m/2dp:dp[k][i][j]=d
阅读全文
摘要:题目大意:给定一棵树的n个节点和n-1条边,对于每个节点,要求去掉它之后所有子树的最大节点数,并输出最大节点数小于n/2的节点编号简单题。两次dfs即可。#include<iostream>#include<fstream>using namespace std;typedef struct e{ int data; e* next;}e;int n;e edge[10001];int d[10001];int v[10001];int dp[10001];int solve(int s){ d[s]=1; v[s]=1; e *p=edge[s].next; whil
阅读全文
摘要:题意:从n个人中选出15人先手,15人后手,求最大能力。简单dp。dp[i][j][k]=max(dp[i-1][j][k-1]+a[k],dp[i][j-1][k]+b[k],dp[i][j][k-1]);dp[i][j][k]表示从k人中选出i个先手,j个后手的最大能力。#include<iostream>#include<fstream>using namespace std;int n;int a[1001],b[1001];int dp[16][16][1001];void read(){// ifstream cin("in.txt");
阅读全文
摘要:题目大意:有n只奶牛进行骑自行车环跑,一分钟跑x圈,领跑的消耗x * x体力,而后面跟跑的消耗x体力。现在输入N, E, D表示有N头奶牛,每头奶牛原先所具有的能量为E,D表示需要环跑的圈数。注意:只要有一只奶牛先达到D圈,就算完成环跑,问奶牛能否完成环跑,如果不能,输出0,否则,输出环跑的最短时间。思路: 最优解必为奶牛1..n-1轮流领跑,奶牛n撞线。且跑了x圈后,未领跑过的奶牛都耗费了x的体力。设dp[i][j][k]表示前i-1头奶牛已领跑,现在由第i头奶牛领跑,一共跑了j圈,奶牛i耗费了k的体力。则dp[i][j][k]可以转移到dp[i][j + p][k + p2](耗费1分钟,
阅读全文
摘要:题意:一城堡的所有的道路形成一个n个节点的树,如果在一个节点上放上一个士兵,那么和这个节点相连的边就会被看守住,问把所有边看守住最少需要放多少士兵。点覆盖问题树形dp或二分图都可以过。代码:View Code #include<iostream>#include<fstream>#include<vector>using namespace std;typedef struct e{ int data; vector<int> a;}e;e edge[1501];int dp[1501][2];int v[1501][2];int n;int s
阅读全文
摘要:题意:插入字符来得到回文串,求插入字符最小数目dp当c[i]==c[j]dp[i][j]=dp[i+1][j-1];否则dp[i][j]=min(dp[i+1][j],dp[i][j-1]) +1;用滚动数组做,不用滚动数组时,可以用short int 水过(比较有趣)。代码:View Code #include<iostream>#include<fstream>using namespace std;char c[5001];int dp[3][5001];void read(){// ifstream cin("in.txt"); int i,
阅读全文
摘要:题目大意:有一些汽车在左岸,你要用一条小破船把它们拉到右岸去。每个测试点包含多个测试数据。第一行的整数C表示测试数据的数目。接下来每个测试数据的第一行为三个整数N, T, M表示一次可以运送N辆汽车,到达对岸的时间为T,汽车的总数是M。接下来的M行每行有一个整数,表示这辆汽车什么时候会来到左岸。对于每个测试数据,输出两个整数,分别是最少要耗用多少时间(包括你等车的时间,就是从0开始直到最后一辆车到达右岸),以及在这个前提下你最少要运送多少次。只要到右岸去就算作一次。dpdp[i]=max(dp[j],a[i])+2*t,(i-n<=j<i).cnt[i]=cnt[j]+1(有待证明
阅读全文