今天上POJ水了几道最简单的DP,却似乎没有一道是依次AC的,相当郁闷。都是因为审题不清,的注意这个问题了!!!!
首先是1157,很简单的DP从左往右有V个花瓶,上往下有F个花,吧F中花放进V个花瓶里面,下面的花必须放在上面的花的右边,每一种搭配方式有一个欣赏值,求这个值的和的最大值。
很简单,就直接用DP[i][j]表示到i,j时候的最大欣赏值
DP[i][j]=MAX(DP[i][j-1],DP[i][j]+DP[i-1][j-1]);
但我却忽略了可能都为负数的情况,所以不能全部直接memset(0);DP[i][0]=-INF这样才对!!!
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #define MAX(a,b) (a) > (b)? (a):(b) 6 #define MIN(a,b) (a) < (b)? (a):(b) 7 #define mem(a) memset(a,0,sizeof(a)) 8 #define INF 1000000007 9 #define MAXN 105 10 using namespace std; 11 12 int DP[MAXN][MAXN]; 13 14 int main() 15 { 16 int F,V; 17 while(~scanf("%d%d",&F,&V)) 18 { 19 int i,j; 20 mem(DP[0]); 21 for(i=1;i<=F;i++) 22 { 23 DP[i][0] = -INF; 24 for(j=1;j<=V;j++) 25 { 26 scanf("%d",&DP[i][j]); 27 DP[i][j]=MAX(DP[i][j-1],DP[i][j]+DP[i-1][j-1]); 28 } 29 } 30 printf("%d\n", DP[F][V]); 31 } 32 return 0; 33 }
然后就是1936,再水不过的DP,我却把Yes写成了YES,No写成了NO。。。。。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <stdio.h> 2 #include <string.h> 3 int main() 4 { 5 char s[100005]={0},t[100005]={0}; 6 while(~scanf("%s %s",s,t)) 7 { 8 int a=strlen(s),b=strlen(t); 9 bool DP = true; 10 int p=0,q=0; 11 while(p<a && q<b) 12 { 13 while(q<b && s[p] != t[q]) 14 { 15 q++; 16 } 17 if(q<b && s[p] == t[q]) 18 { 19 p++; 20 q++; 21 } 22 } 23 if(p!=a && q==b)DP=false; 24 printf("%s\n",DP?"Yes":"No"); 25 } 26 return 0; 27 }
最后就是这道题,坑死人!!!!!!!!!!!!!
感觉不像是DP,没有DP做,但是错了很多次,还是写一下。前面两次是OLE,不明原因。。。。。
改为不是多组输入后。就。。。。。(但我的多组输入没问题啊!!!!)
思路就是每一个顶点的度数除以这个并查集内所有度的和就是这个定点所占的比例。那就只需要并查集一下就可以了。然后就是每加一条边,这个并查集内的总和就+2,定点+1。
把总的值保留在根节点中就可以了。。num[a]是以a为根节点的次并查集总度数,ma[a]就是总和
但题目坑爹的就在于说那个值是实数而且最后的结果保留三位小数,这样又WA了两次
1 #include <cstdio> 2 #include <cstring> 3 #define MAXN 105 4 using namespace std; 5 6 int p[MAXN],sum[MAXN],d[MAXN],num[MAXN]; 7 double ma[MAXN]; 8 int N,M; 9 10 int find(int x) 11 { 12 return x==p[x]?x:p[x]; 13 } 14 15 void merg(int x,int y) 16 { 17 d[x]++;d[y]++; 18 int a = find(x); 19 int b = find(y); 20 if(a != b) 21 { 22 if(a<b){p[b]=a;ma[a]+=ma[b];num[a]+=2;} 23 else {p[a]=b;ma[b]+=ma[a];num[b]+=2;} 24 } 25 else num[a]+=2; 26 } 27 28 int main() 29 { 30 int T; 31 scanf("%d",&T); 32 while(T--) 33 { 34 int i,a,b; 35 memset(sum,0,sizeof(sum)); 36 memset(num,0,sizeof(num)); 37 memset(d,0,sizeof(d)); 38 scanf("%d%d",&N,&M); 39 for(i=1;i<=N;i++) 40 { 41 scanf("%lf",&ma[i]);//输入的是实数。。。 42 p[i]=i; 43 } 44 for(i=1;i<=M;i++) 45 { 46 scanf("%d%d",&a,&b); 47 merg(a,b); 48 } 49 for(i=1;i<=N;i++) 50 { 51 if(!d[i]){printf("%.3lf\n",ma[i]);continue;}//保留三位小数 52 else printf("%.3lf\n",(double)(d[i]*ma[p[i]])/(double)num[p[i]]); 53 } 54 printf("\n"); 55 } 56 return 0; 57 }
不管怎么说,这篇就当做是提醒自己看题吧,尤其是英文题,特别要注意!!!!!!!!!!!!!!