BZOJ 1673 [Usaco2005 Dec]Scales 天平:dfs 启发式搜索 A*搜索

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1673

题意:

  有n个砝码(n <= 1000),重量为w[i]。

  你要从中选择一些砝码,使得这些砝码的总重量最大,但不超过c。

  w[i]按递增顺序给出,并且保证w[i] >= w[i-1]+w[i-2] (i >= 3)。

 

题解:

  dfs。

  因为w[i] >= w[i-1]+w[i-2],所以其实n最大只有45左右(类似斐波那契数列)。

 

  优化:

    (1)启发式:优先选砝码(不跳过),并且优先选重量大的砝码,尽早更新ans。

    (2)A*搜索:如果当前tot + 剩下砝码的总重(前缀和) < ans,则return。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAX_N 1005
 5 
 6 using namespace std;
 7 
 8 int n,c;
 9 int ans=0;
10 int w[MAX_N];
11 long long sum[MAX_N];
12 
13 void dfs(int col,int tot)
14 {
15     if(tot>c) return;
16     ans=max(ans,tot);
17     if(col>n) return;
18     if(tot+sum[n]-sum[col-1]<=ans) return;
19     dfs(col+1,tot+w[col]);
20     dfs(col+1,tot);
21 }
22 
23 void read()
24 {
25     cin>>n>>c;
26     for(int i=n;i>=1;i--)
27     {
28         cin>>w[i];
29     }
30 }
31 
32 void solve()
33 {
34     sum[0]=0;
35     for(int i=1;i<=n;i++)
36     {
37         sum[i]=sum[i-1]+w[i];
38     }
39     dfs(1,0);
40 }
41 
42 void print()
43 {
44     cout<<ans<<endl;
45 }
46 
47 int main()
48 {
49     read();
50     solve();
51     print();
52 }

 

posted @ 2017-10-07 10:58  Leohh  阅读(253)  评论(0编辑  收藏  举报