【砝码称重】

题目

Bitset做法代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
bitset<N*2> bs;
int main()
{
    bs.set(100000);
    
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        int x;
        scanf("%d", &x);
        bs = bs | bs << x | bs >> x; //bs << x 每位向高索引方向移动x,意味着之前的每个值都加了x,把bool值带到的新的高位(超出舍弃)
    }
    
    printf("%d", bs.count() / 2);
}
//注意 bs = 00000, bs.set(0)后是 00001(与我们的直觉相反,但是反过来理解即可)

背包做法代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110, M = 1e5+10, off = M;
int w[N];
int f[N][2*M];
int n, m;
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", w+i), m += w[i];
        
    f[0][0+off] = 1;
    for(int i = 1; i <= n; i++)
    {
        for(int j = -m; j <= m; j++)
        {
            f[i][j+off] = f[i-1][j+off];
            if(j - w[i] >= -m) f[i][j+off] |= f[i-1][j-w[i]+off];
            if(j + w[i] <= m) f[i][j+off] |= f[i-1][j+w[i]+off];
        }
    }
    
    int res = 0;
    for(int i = 1; i <= m; i++)
    {
        res += (f[n][i+off]);
    }
    
    printf("%d", res);
}

不用偏移量,带绝对值的做法代码

  • 绝对值相同的正负值是可以统一存储在一个空间的
    • 因为这两种是可以同时做到的
  • 之前的做法是,我们需要负值,就去负值+off那里找;现在的做法是去对应的正值那里找
cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

const int N = 110, M = 2e5 + 10;
int sum;
int n;
int w[N];
bool f[N][M];

int main() {

    cin>>n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &w[i]);
        sum+=w[i];
    }

    f[0][0]=true;

    for (int i = 1; i <= n;i++)
        for (int j = 0; j <=sum;j++)
            f[i][j]=f[i-1][j]||f[i-1][j+w[i]]||f[i-1][abs(j-w[i])];
                //只要有一个非空,f[i][j]就非空
    int ans = 0;
    for (int i = 1; i <=sum;i++)
        if(f[n][i])ans++;//不为零说明可以选出这个质量的砝码

    cout << ans;

    return 0;
}

因此没有必要开两倍,我们存的大小的应该等于正数数目,大于最大值的都非法

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

const int N = 110, M = 1e5 + 10;
int sum;
int n;
int w[N];
bool f[N][M];

int main() {

    cin>>n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &w[i]);
        sum+=w[i];
    }

    f[0][0]=true;

    for (int i = 1; i <= n;i++)
        for (int j = 0; j <=sum;j++)
        {    
            f[i][j]=f[i-1][j]||f[i-1][abs(j-w[i])];
            if (j + w[i] <= sum) f[i][j] |= f[i - 1][j + w[i]];
        }    
                //只要有一个非空,f[i][j]就非空
    int ans = 0;
    for (int i = 1; i <=sum;i++)
        if(f[n][i])ans++;//不为零说明可以选出这个质量的砝码

    cout << ans;

    return 0;
}
相关推荐
多多*10 分钟前
牛客周赛 Round 114 Java题解
算法
他们叫我一代大侠25 分钟前
Leetcode :模拟足球赛小组各种比分的出线状况
算法·leetcode·职场和发展
Nebula_g28 分钟前
C语言应用实例:硕鼠游戏,田忌赛马,搬桌子,活动选择(贪心算法)
c语言·开发语言·学习·算法·游戏·贪心算法·初学者
AI科技星1 小时前
张祥前统一场论动量公式P=m(C-V)误解解答
开发语言·数据结构·人工智能·经验分享·python·线性代数·算法
海琴烟Sunshine1 小时前
leetcode 345. 反转字符串中的元音字母 python
python·算法·leetcode
geobuilding2 小时前
将大规模shp白模贴图转3dtiles倾斜摄影,并可单体化拾取建筑
算法·3d·智慧城市·数据可视化·贴图
jghhh012 小时前
基于高斯伪谱法的弹道优化方法及轨迹仿真计算
算法
mm-q29152227293 小时前
【天野学院5期】 第5期易语言半内存辅助培训班,主讲游戏——手游:仙剑奇侠传4,端游:神魔大陆2
人工智能·算法·游戏
MoRanzhi12034 小时前
Python 实现:从数学模型到完整控制台版《2048》游戏
数据结构·python·算法·游戏·数学建模·矩阵·2048
2401_841495644 小时前
【数据结构】基于BF算法的树种病毒检测
java·数据结构·c++·python·算法·字符串·模式匹配