_xiaobai_

导航

zoj1558 Euro Efficiency(DP)

/*
 背包变形:如果按照完全背包计算会有后效性,所以用01背包计算
 注意两点:1.数据的范围,因为要做差,所以数据要超过100
     2.背包时物品的顺序,本题的解会受到顺序影响,
      所以先对所有数据01背包,然后再次01背包。

 补充:忽然发现bfs是DP,按广度为阶段,并且每个值最求一次#24
*/

View Code
 1 #include <stdio.h>
2 #include <iostream>
3
4 using namespace std;
5
6 int F[ 205 ];
7 int C[ 7 ];
8
9 int main()
10 {
11 int T;
12 while ( ~scanf("%d",&T))
13 while ( T -- ) {
14 for ( int i = 1 ; i <= 6 ; ++ i )
15 scanf("%d",&C[ i ]);
16
17 for ( int i = 0 ; i <= 200 ; ++ i )
18 F[ i ] = i;
19
20 for ( int k = 0 ; k <= 100 ; ++ k )
21 for ( int i = 6 ; i >= 1 ; -- i ) {
22 for ( int j = 200 ; j >= C[ i ] ; -- j )
23 if ( F[ j ] > F[ j-C[ i ] ] + 1 )
24 F[ j ] = F[ j-C[ i ] ] + 1;
25 for ( int j = 0 ; j <= 200-C[ i ] ; ++ j )
26 if ( F[ j ] > F[ j+C[ i ] ] + 1 )
27 F[ j ] = F[ j+C[ i ] ] + 1;
28 }
29
30 int Sum = 0,Max = 0;
31 for ( int i = 1 ; i <= 100 ; ++ i ) {
32 Sum += F[ i ];
33 if ( Max < F[ i ] )
34 Max = F[ i ];
35 }
36
37 printf("%d.%d %d\n",Sum/100,Sum%100,Max);
38 }
39 return 0;
40 }

/*
 bfs解法:从6个基本点向外发散,每次增一,更新节点,每个节点被标记是一定为最小

      按半径为100扫描
*/

View Code
 1 #include<iostream>
2 #include<cstdlib>
3 using namespace std;
4
5 int coin[ 6 ];
6 int sign[ 301 ];
7 int leat[ 301 ];
8 int queu[ 301 ];
9
10 int main()
11 {
12 int t;cin >> t;
13 while ( t -- )
14 {
15 for ( int i = 0 ; i < 6 ; ++ i )
16 cin >> coin[ i ];
17 memset( sign , 0 , sizeof( sign ) );
18 for ( int i = 0 ; i < 6 ; ++ i )
19 {
20 sign[ coin[ i ]+100 ] = 1;
21 leat[ coin[ i ]+100 ] = 1;
22 queu[ i ] = coin[ i ]+100;
23 }
24 int move = 0,save = 6;
25 while ( move < save )
26 {
27 int p = queu[ move ];
28 for ( int k = 0 ; k < 6 ; ++ k )
29 {
30 /* 增加 */
31 int q = p + coin[ k ];
32 if ( q >= 0 && q < 301 && !sign[ q ] )
33 {
34 sign[ q ] = 1;
35 queu[ save ++ ] = q;
36 leat[ q ] = leat[ p ] + 1;
37 }
38 /* 减少 */
39 q = p - coin[ k ];
40 if ( q >= 0 && q < 301 && !sign[ q ] )
41 {
42 sign[ q ] = 1;
43 queu[ save ++ ] = q;
44 leat[ q ] = leat[ p ] + 1;
45 }
46 }
47 ++ move;
48 }
49 double sum = 0.0;
50 int max = 0;
51 for ( int i = 101 ; i < 201 ; ++ i )
52 {
53 sum += leat[ i ];
54 if ( leat[ i ] > max )
55 max = leat[ i ];
56 }
57 printf("%.2f %d\n",sum/100.0,max);
58 }
59 }

posted on 2011-08-18 01:06  _xiaobai_  阅读(320)  评论(0编辑  收藏  举报