zoukankan      html  css  js  c++  java
  • P1441 砝码称重 DFS回溯+DP

    题目描述

    现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。

    请注意,砝码只能放在其中一边。

    输入输出格式

    输入格式:

    输入文件weight.in的第1行为有两个整数n和m,用空格分隔

    第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。

    输出格式:

    输出文件weight.out仅包括1个整数,为最多能称量出的重量数量。

    输入输出样例

    输入样例#1: 复制
    3 1
    1 2 2
    输出样例#1: 复制
    3

    说明

    【样例说明】

    在去掉一个重量为2的砝码后,能称量出1,2,3共3种重量。

    【数据规模】

    对于20%的数据,m=0;

    对于50%的数据,m≤1;

    对于50%的数据,n≤10;

    对于100%的数据,n≤20,m≤4,m<n,ai≤100。

    一开始总想着骚操作  但是细节太多处理不了

    直接暴力搜索就能过的。。。。

    没任何优化  1600ms

    #include<bits/stdc++.h>
    using namespace std;
    //input b y bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    #define N  20+9
    
    int n,m;
    int vis[N];
    int a[N];
    int q[N];
    int dp[2010];
    int cnt;
    int maxx;
    
    void dp1()
    {
        CLR(dp,0);
        dp[0]=1;
        int cnt=0;
        rep(i,1,n)
        if(vis[i])
        {
            repp(j,2000,0)
            if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=1,cnt++;
        }
        maxx=max(maxx,cnt);
    }
    
    
    void dfs(int cur,int num)
    {
        if(num>n-m)return ;
        if(num==n-m)
        {
         dp1();
         return ;
        }
        rep(i,cur,n)
        if(!vis[i])
        {
            vis[i]=1;
            dfs(i+1,num+1);
            vis[i]=0;
        }
        return ;
    }
    
    
    int main()
    {
        RII(n,m);
        rep(i,1,n)
        RI(a[i]);
        
        maxx=0;
        dfs(1,0);
        cout<<maxx;
        return 0;
    }
    View Code

    加一个dp上界的优化   950ms

    #include<bits/stdc++.h>
    using namespace std;
    //input b y bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    #define N  20+9
    
    int n,m;
    int vis2[200];
    int vis[N];
    int a[N];
    int q[N];
    int dp[2010];
    int cnt;
    int tot;
    int maxx;
    
    void dp1()
    {
        CLR(dp,0);
        dp[0]=1;
        int cnt=0;
        rep(i,1,n)
        if(vis[i])
        {
            repp(j,tot,0)
            if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=1,cnt++;
        }
        maxx=max(maxx,cnt);
    }
    
    void dfs(int cur,int num)
    {
        if(num>n-m)return ;
        if(num==n-m)
        {
         dp1();
         return ;
        }
        rep(i,cur,n)
        if(!vis[i])
        {
            vis[i]=1;
            dfs(i+1,num+1);
            vis[i]=0;
        }
        return ;
    }
    
    int main()
    {
        RII(n,m);
        tot=0;
        rep(i,1,n)
        RI(a[i]),tot+=a[i];
    
        maxx=0;
        dfs(1,0);
        cout<<maxx;
        return 0;
    }
    View Code

    再次上界优化  400ms!!!!

    #include<bits/stdc++.h>
    using namespace std;
    //input b y bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    //////////////////////////////////
    #define N  20+9
    int n,m;
    int vis[N];
    int a[N];
    int dp[2010];
    int cnt;
    int maxx;
    
    void dp1()
    {
        CLR(dp,0);
        dp[0]=1;
        int cnt=0;
        int tot=0;
        rep(i,1,n)
        if(vis[i])
        {
            repp(j,tot,0)
            if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=1,cnt++;
            tot+=a[i];
        }
            maxx=max(maxx,cnt);
    }
    
    void dfs(int cur,int num)
    {
        if(num>n-m)return ;
        if(num==n-m)
        {
         dp1();
         return ;
        }
        rep(i,cur,n)
        if(!vis[i])
        {
            vis[i]=1;
            dfs(i+1,num+1);
            vis[i]=0;
        }
        return ;
    }
    
    int main()
    {
        RII(n,m);
        rep(i,1,n)
        RI(a[i]);
    
        maxx=0;
        dfs(1,0);
        cout<<maxx;
        return 0;
    }
    View Code

      

  • 相关阅读:
    JS仿淘宝网顶部的导航菜单
    JS+CSS打造高仿XP默认主题菜单样式
    Jquery打造网页右上角可伸缩关闭的菜单
    来自百度百科的目录显示/隐藏效果
    Jquery打造的下拉层式菜单
    javascript小數位四舍五入[IE5.5+]
    css外容器margin問題[IE中height:100%]
    EXEC执行动态SQL时取出变量值[EXEC函数只能是局部变量]
    sql一列变多列
    判斷日期,輸出成YYYY/MM/DD形式
  • 原文地址:https://www.cnblogs.com/bxd123/p/10736650.html
Copyright © 2011-2022 走看看