2019-03-23 [蓝桥杯][算法提高VIP]盾神与砝码称重

题目描述
有一天,他在宿舍里无意中发现了一个天平!这 个天平很奇怪,有n个完好的砝码,但是没有游码。盾神为他的发现兴奋不已!于是他准备去称一称自己的东西。他准备好了m种物品去称。神奇的是,盾神一早就 知道这m种物品的重量,他现在是想看看这个天平能不能称出这些物品出来。但是盾神稍微想了1秒钟以后就觉得这个问题太无聊了,于是就丢给了你。

数据规模和约定
1< =n< =24, 1< =m< =10.
输入
第一行为两个数,n和m。
第二行为n个数,表示这n个砝码的重量。
第三行为m个数,表示这m个物品的重量。
输出
输出m行,对于第i行,如果第i个物品能被称出,输出YES否则输出NO。
样例输入
4 2
1 2 4 8
15 16
样例输出
YES
NO
提示
C语言在线学习平台微信号dotcpp
来源
算法提高

使用动态规划是错误的方法,因为没有知道质量砝码质量的前提下不知道数组如何设置大小,所以大部分的数据都不能通过。

#include<iostream>
#include<algorithm>
using namespace std;
int m,n;
int A[30],w[11];
bool dp[1000][1000];
long long sum;
int main(void)
{
    freopen("D:\\input2.txt","r",stdin); 
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>A[i];
    for(int i=1;i<=m;i++) cin>>w[i];
    for(int i=1;i<=n;i++) sum+=A[i];
    cout<<"sum="<<sum<<endl;
    dp[0][sum]=true;//表示可以使用0个砝码组成质量为0的组成 
    for(int i=1;i<=n;i++)//枚举n个物品 
    {
        for(int j=0;j<=sum*2;j++)//枚举n个物品可能组成的质量 
        {
            if(j>=A[i]) if(dp[i-1][j-A[i]]) dp[i][j]=true;//如果前i-1个砝码质量为j-A[i]那么可以组合成j 
            if(dp[i-1][j+A[i]]) dp[i][j]=true;//如果前i个可以组合成j+A[i],那么可以去掉这个砝码组成j 
            dp[i][j]=max(dp[i][j],dp[i-1][j]);//放置断层 
        }
    }
    /*
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=2*sum;j++)
        {
            printf("dp[%d][%d]=%d  ",i,j,dp[i][j]);
        }
        printf("\n");
    }
    */
    for(int i=0;i<=sum*2;i++)
    {
        if(dp[n][i])
        {
            cout<<i-sum<<" ";   
        } 
    } 
    cout<<endl;
    
    for(int i=1;i<=m;i++)
    {
        if(dp[n][sum-w[i]] || dp[n][sum+w[i]]) cout<<"YES"<<endl;
        else cout<<"NO"<<endl; 
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容