poj1770

题目意思:给定N个数,在给定M个数,现在在N中取数,满足取到得数任意两者之差都不等与M个数中的任意一个。。求最多取多少个数。

思路:把有冲突的数之间连一条边(这样出来竟然没环,而是数,太神奇了)

         然后进行树形dp

         f[i][0]表示第i个节点不取取得的最大个数

         f[i][1]则表示取

        f[i][0] = sigma(max(f[j][0],f[j][1])); 

        f[i][1]= sigma(f[j][0]);

        j为i的子树。。

 1 /*
 2   Time:2013-03-11 09:23:07
 3   State:Accepted
 4 */
 5 #include <iostream>
 6 #include <cstring>
 7 #include <cstdlib>
 8 #include <cstdio>
 9 #include <algorithm>
10 #include <cmath>
11 using namespace std;
12 int n, m , f[210][3], map[210][210] , a[210] , b[210];
13 
14 void init(){
15      memset(map, 0 , sizeof(map));
16      memset(f , 0 , sizeof(f));
17      for (int i = 1; i <= n; ++i)
18         scanf("%d", &a[i]);
19      for (int i = 1; i <= m ;++i)
20         scanf("%d", &b[i]);
21      for (int i = 1; i < n; ++i)
22         for  (int j = i + 1 ; j <= n; ++j)
23             for (int k = 1; k <= m; ++k )
24                 if (a[i]-a[j] == b[k] || a[j]-a[i] == b[k])
25                          map[i][j] = map[j][i] = 1;
26                      
27             
28 }
29 
30 int dp(int fa ,int x , int k){
31     if (f[x][k]) return f[x][k];
32     int temp = 0;
33        for (int y = 1; y <= n ; ++y)
34            if (fa != y && map[x][y])
35              if (k == 0) temp += max(dp(x , y , 0), dp(x, y, 1));
36              else temp += dp(x, y, 0);
37     temp += a[x]*k;
38     f[x][k] = temp;
39     return temp;
40 }
41 
42 int main(){
43      freopen("poj1770.in","r",stdin);
44      freopen("poj1770.out","w",stdout);
45      while (scanf("%d%d" , &n , &m)!=EOF && n)
46         {
47            init();
48            printf("%d\n",max(dp(-1, 1, 0), dp(-1, 1, 1)));
49         }
50 }

 

posted on 2013-03-24 00:03  yzcstc  阅读(178)  评论(0编辑  收藏  举报