简单DP入门四连发

复习一下一直不太懂的dp.

dp博大精深,路还长着呢

第一题;http://acm.hdu.edu.cn/showproblem.php?pid=2084

从下往上就是水题

 1 #include<cstdio>
 2 using namespace std;
 3 int max(int x,int y)
 4 {
 5     if (x<y) return y;
 6     else return x;
 7 }
 8 int main()
 9 {
10     int t,n,yj[101][101],i,j;
11     scanf("%d",&t);
12     while (t--)
13     {
14         scanf("%d",&n);
15         for (i=1;i<=n;i++)
16         {
17             for (j=1;j<=i;j++)
18                 scanf("%d",&yj[i][j]);
19         }
20         for (i=n-1;i>=1;i--){
21             for (j=1;j<=i;j++)
22                 yj[i][j]+=max(yj[i+1][j],yj[i+1][j+1]);
23         }
24         printf("%d
",yj[1][1]);
25     }
26     return 0;
27 }

第二题;http://acm.hdu.edu.cn/showproblem.php?pid=1231

与贪心有点像,样例能过基本就能A

 1 #include<cstdio>
 2 using namespace std;
 3 int a[10001];
 4 int main()
 5 {
 6     int n,sum,mn,sx,sy,x,i;
 7     while (~scanf("%d",&n))
 8     {
 9         if (!n) break;
10         int flag=0;
11         for (i=1;i<=n;i++)
12         {
13             scanf("%d",&a[i]);
14             if (a[i]>=0) flag=1;
15         }
16         if (!flag)
17         {
18             printf("0 %d %d
",a[1],a[n]);
19             continue;
20         }
21         sum=0,mn=-100000;
22         sx=sy=x=1;
23         for (i=1;i<=n;i++)
24         {
25             sum+=a[i];
26             if (sum<0)
27             {
28                 while (a[i]<0&&i<=n)
29                     i++;
30                 if (i<=n)
31                 {
32                     x=i;sum=a[i];
33                 }
34                 else break;
35             }
36             if (sum>mn)
37             {
38                 sy=i;
39                 sx=x;
40                 mn=sum;
41             }
42         }
43         printf("%d %d %d
",mn,a[sx],a[sy]);
44     }
45     return 0;
46 }

第三题;http://acm.hdu.edu.cn/showproblem.php?pid=1003

和第二题差不多,只不过变成了输出头和尾的序号,注意这题对都是负数没有特别输出了,要求不同

 1 #include<cstdio>
 2 using namespace std;
 3 int a[100001];
 4 int main()
 5 {
 6     int t,ans=1,i,n,sum,sx,sy,x;
 7     scanf("%d",&t);
 8     while (t--)
 9     {
10         scanf("%d",&n);
11         int flag=0,mx=-100000;
12         for (i=1;i<=n;i++)
13         {
14             scanf("%d",&a[i]);
15             if (mx<a[i]) mx=a[i],sx=sy=i;
16             if (a[i]>=0) flag=1;
17         }
18         printf("Case %d:
",ans++);
19         if (flag==0)
20         {
21             printf("%d %d %d
",mx,sx,sy);
22             if (t!=0) printf("
");
23             continue;
24         }
25         sum=0,sx=1,sy=1,x=1;
26         int mn=-100000;
27         for (i=1;i<=n;i++)
28         {
29              sum+=a[i];
30              if (sum<0)
31              {
32                  while (a[i]<0&&i<=n)
33                     i++;
34                  if (i<=n)
35                  {
36                      x=i;sum=a[i];
37                  }
38                  else break;
39              }
40              if (mn<sum)
41              {
42                  sx=x;
43                  sy=i;
44                  mn=sum;
45              }
46         }
47         printf("%d %d %d
",mn,sx,sy);
48         if (t!=0) printf("
");
49     }
50     return 0;
51 }

第四题;http://acm.hdu.edu.cn/showproblem.php?pid=1087

求递增序列的最大和,有个题意设置的坑就是这个递增序列可以不连续

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int i,j,n,max,t;
 5     int a[1001];
 6     int sum[1001];
 7     while(~scanf("%d",&n))
 8     {
 9         if (n==0)
10             break;
11         for(i=0;i<n;i++)
12         {
13             scanf("%d",&a[i]);
14             sum[i]=a[i];
15         }
16         t=0;
17         for(j=0;j<n;j++)
18         {
19             max=0;
20             for(i=0;i<=j;i++)
21             {
22                 if(a[i]<a[j])
23                 {
24                     if(sum[i]>max)
25                         max=sum[i];
26                 }
27             }
28             sum[j]=max+a[j];
29             if (sum[j]>t)
30                 t=sum[j];
31         }
32         printf("%d
",t);
33     }
34     return 0;
35 }
原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4876013.html