POJ 3186 Treats for the Cows ——(DP)

  第一眼感觉是贪心,,果断WA。然后又设计了一个两个方向的dp方法,虽然觉得有点不对,但是过了样例,交了一发,还是WA,不知道为什么不对= =,感觉是dp的挺有道理的,,代码如下(WA的):

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 const int N = 2000 + 5;
 6 
 7 int a[N];
 8 int dp[N][N];
 9 int n;
10 
11 int getDay(int i,int j)
12 {
13     return n - (j - i) + 1;
14 }
15 
16 int main()
17 {
18     while(scanf("%d",&n) == 1)
19     {
20         for(int i=1;i<=n;i++) scanf("%d",a+i);
21         memset(dp,0,sizeof dp);
22         for(int i=1;i<=n;i++)
23         {
24             for(int j=i+1;j<=n+1;j++) dp[i][j] = max(dp[i][j], dp[i-1][j] + getDay(i,j) * a[i]);
25         }
26         for(int j=n+1;j>=1;j--)
27         {
28             for(int i=j-1;i>=0;i--) dp[i][j] = max(dp[i][j], dp[i][j+1] + getDay(i,j) * a[j]);
29         }
30         int ans = 0;
31         for(int i=0;i<=n;i++) ans = max(ans, dp[i][i+1]);
32         printf("%d
",ans);
33     }
34     return 0;
35 }
WA的DP

  看了别人的博客以后,有一个不错的dp方法:dp[i][j]表示左边已经选了i个右边已经选了j个最大值,然后转移也很明显。AC代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 const int N = 2000 + 5;
 6 
 7 int a[N];
 8 int dp[N][N];
 9 int n;
10 
11 int main()
12 {
13     while(scanf("%d",&n) == 1)
14     {
15         for(int i=1;i<=n;i++) scanf("%d",a+i);
16         memset(dp,0,sizeof dp);
17         for(int i=0;i<=n;i++)
18         {
19             for(int j=0;i+j<=n;j++)
20             {
21                 if(i > 0) dp[i][j] = max(dp[i][j], dp[i-1][j] + a[i] * (i+j));
22                 if(j > 0) dp[i][j] = max(dp[i][j], dp[i][j-1] + a[n-j+1] * (i+j));
23             }
24         }
25         int ans = 0;
26         for(int i=0;i<=n;i++) ans = max(ans, dp[i][n-i]);
27         printf("%d
",ans);
28     }
29     return 0;
30 }
原文地址:https://www.cnblogs.com/zzyDS/p/6407161.html