【杂题】【动态规划】【搜索】——洛谷P1441砝码称重

时间:2019-09-23
本文章向大家介绍【杂题】【动态规划】【搜索】——洛谷P1441砝码称重,主要包括【杂题】【动态规划】【搜索】——洛谷P1441砝码称重使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

GO:传送门


搜索+动态规划问题。

参考自:这位大大的题解

搜索方面很简单,选出m个数即可,而在剩下的部分中选择几个数就比较难想。

那么我们用01背包来解决。

设dp[i][j]表示当前选第j个数,能否构成重量i。

dp[i][j]=dp[j-a[i]][j-1]||dp[i][j],而发现j只和j-1有关,考虑滚动数组优化:

dp[j+a[i]]=dp[j],j通过枚举来实现。

比较适当的枚举范围可以以之前的a[i]之和为上界,因为已经经过的状态不会高于这个数值。

题目就解出来了!

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,tot,ans,maxans;
 4 int a[25];
 5 int vis[25];
 6 bool dp[2010];
 7 inline int read(){ 
 8     int x=0,f=1;
 9     char c=getchar();
10     while(!isdigit(c)){
11         if(c=='-') f=-1;
12         c=getchar();
13     }
14     while(isdigit(c)){
15         x=x*10+c-'0';
16         c=getchar();
17     }
18     return x*f;
19 }
20 inline void getans(){
21     memset(dp,0,sizeof(dp));
22     dp[0]=1;ans=0;tot=0;
23     for(register int i=1;i<=n;i++){
24         if(vis[i]) continue;
25         for(register int j=tot;j>=0;j--){
26             if(dp[j]&&!dp[j+a[i]]) dp[j+a[i]]=1,ans++;
27         }
28         tot+=a[i];
29     }
30     maxans=max(maxans,ans);
31 }
32 void dfs(int now,int won){
33     if(won>m) return;
34     if(now>n){
35         if(won==m) getans();
36         return;
37     }
38     dfs(now+1,won);
39     vis[now]=1;
40     dfs(now+1,won+1);
41     vis[now]=0;
42 }
43 int main(){
44     n=read();m=read();
45     for(register int i=1;i<=n;i++){
46         a[i]=read();
47     }
48     dfs(1,0);
49     printf("%d",maxans);
50     return 0;
51 } 

原文地址:https://www.cnblogs.com/Nelson992770019/p/11573293.html