POJ3176-基础DP
很基础的dp题。有一头奶牛想接尽量多的苹果,有w此移动机会。
dp[i][w] = max(dp[i-1][w+1] + 能否吃到苹果 ,dp[i-1][w] + 能否吃到苹果) //从上一分钟是否移动中选出最大值转移
我开始状态转移方程没写错,但是边界条件总是写不好,不能处理0。并不是这样的,刚刚又看了一下代码,加号的优先级高于位运算!!!
想起来了线段树不用i>>1+1而用i>>1|1 了。。。。
后来今天问了妹子,还是专业dp的妹子稳啊,理清了边界条件一遍就A了。
以后写dp要想好状态转移的过程,想好再写。
1 #include <algorithm> 2 #include <cstring> 3 #include <ctype.h> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <string> 8 #include <queue> 9 #include <stack> 10 #include <cmath> 11 #include <set> 12 #include <map> 13 14 using namespace std; 15 16 int N,M,T,W; 17 int apple[1010],dp[1010][1010]; 18 int main() 19 { 20 while(~scanf("%d%d",&T,&W)) 21 { 22 int ans = 0; 23 for(int i=0;i<T;i++) scanf("%d",&apple[i]); 24 memset(dp,0,sizeof dp); 25 dp[0][W] = (apple[0]-1)^(W%2); 26 for(int i=1;i<T;i++) 27 { 28 //dp[i][0] = (apple[i]-1) + dp[i-1][0]; 29 for(int w = W;w >= 0; w--) 30 { 31 if(w == W) dp[i][w] = dp[i-1][w] + ((apple[i]-1)^(w%2)); 32 else dp[i][w] = max(dp[i-1][w+1] + ((apple[i]-1)^((w+1)%2)),dp[i-1][w] + ((apple[i]-1)^(w%2))); 33 ans = max(ans,dp[i][w]); 34 } 35 } 36 memset(dp,0,sizeof dp); 37 dp[0][W] = !((apple[0]-1)^(W%2)); 38 for(int i=1;i<T;i++) 39 { 40 //dp[i][0] = (apple[i]-1) + dp[i-1][0]; 41 for(int w = W;w >= 0; w--) 42 { 43 if(w == W) dp[i][w] = dp[i-1][w] + !((apple[i]-1)^(w%2)); 44 else dp[i][w] = max(dp[i-1][w+1] + !((apple[i]-1)^((w+1)%2)),dp[i-1][w] + !((apple[i]-1)^(w%2))); 45 ans = max(ans,dp[i][w]); 46 } 47 } 48 printf("%d\n",ans); 49 } 50 }