• 【杂题】【动态规划】【搜索】——洛谷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 } 
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    POJ 1006 ( 中国剩余定理 )
    HDU 2736 Surprising Strings
    STL----map 章节
    最短路问题
    [HAOI2007]反素数
    严格次小生成树[BJWC2010]
    P3320 [SDOI2015]寻宝游戏(LCA)
    [Violet]樱花/阶乘分解
    [HNOI2008]GT考试
    2012 年国家集训队互测 Tree
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11573293.html
Copyright © 2020-2023  润新知