P1441 砝码称重

中文题

 

想法:

首先第一个要解决的问题就是在 n 个砝码中取 m 个 (因为数据量不是很大,我们可以考虑直接暴力)

当已知 m 个砝码的时候,求有多少中搭配的方式 (这个可以采取dp的方式)

 

#pragma GCC optimize(3,"Ofast","inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

const double eps = 1e-10;
const int maxn = 30 + 10;
const LL mod = 998244353;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

int a[maxn];
int vis[maxn];
int cnt,sum,ans;
int n,m;
int vised[2010];

void dp() {
    memset(vised,0, sizeof(vised));
    vised[0] = 1;
    cnt = 0;
    sum = 0;
    for (int i = 1;i <= n;i++) {
        if (vis[i])
            continue;
        sum += a[i];
        for (int j = sum;j >= a[i];j--) {
            if (vised[j-a[i]] && j >= a[i] && !vised[j]) {
                vised[j] = 1;
                cnt++;
            }
        }
    }
    //cout << cnt << endl;
    ans = max(ans,cnt);
}


void dfs(int cur,int now) {
    if (now > m+1)
        return ;
    if (cur == n+1) {
        if (now == m+1) {
            dp();
        }
        return ;
    }
    vis[cur] = 1;
    dfs(cur+1,now+1);
    vis[cur] = 0;
    dfs(cur+1,now);
}

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    ans = 0;
    for (int i = 1;i <= n;i++) {
        cin >> a[i];
        //sum += a[i];
    }
    dfs(1,1);
    cout << ans << endl;
    return 0;
}

 

posted @ 2020-03-23 19:37  _Ackerman  阅读(290)  评论(0编辑  收藏  举报