2.14学习总结

https://www.luogu.com.cn/record/102157012

题解:

1.定义数组dp数组含义:dp[i]表示的是以 i 为结果的重量是否出现过;

2.找规律: 只有当 k 为质量的结果出现过,才能标记 k+w[i];

if(dp[k]==1&&k+w[i]<=1000)   dp[k+w[i]]=1;

3.初始化:dp[0]=1;一个砝码都不用是可以理论上是可以成立的;但由于题目要求不包括一个砝码都不用的情况,所以最后找不同质量的个数的时候要从下标1开始。 

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
using namespace std;
int w[7]={0,1,2,3,5,10,20};//单个砝码质量
int a[7];//砝码数量
const int N=1e3+10;
int dp[N];
int main()
{
    dp[0]=1;
    for(int i=1;i<=6;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=6;i++)//单个砝码的质量
    {
        for(int j=1;j<=a[i];j++)//循环砝码的个数
        {
            for(int k=1000;k>=0;k--)//砝码的总质量小于1000,所以这是最大的价值
            {
                if(dp[k]==1&&k+w[i]<=1000)//只有当k为质量的结果出现过,才能标记k+w[i]
                {
                    dp[k+w[i]]=1;
                }
            }
        }
    }
    int cnt=0;
    for(int i=1;i<=1000;i++)//从1开始找个数
    {
        if(dp[i]==1)
            cnt++;
    }
    printf("Total=%d\n",cnt);
    return 0;
}

 https://www.luogu.com.cn/record/102165192

题解:

1.定义数组dp的含义:d[i][j]表示的是第 i-1 个砝码是达到的 j 重量;

2.找规律:

 如果 i-1 个砝码已经到达 j 质量并且标记过:if (dp[i-1][j])

  1.  选择不放第 i 个砝码:dp[i][j] = d[i-1][j];
  2.  选择将第 i 个砝码放右边,所以总重量增加: dp[i][j + a[i]] = 1
  3. 选择第 i 个砝码左边放在左边,此时 j 的质量是左右相差的绝对值:dp[i][abs(j - a[i])] = 1;

特殊情况:如果第 i 个砝码和 j 的重量相等,由于可以只放一个砝码,所以此时的 dp[i][j]=1;

3.初始化:dp[0]=1;一个砝码都不用是可以理论上是可以成立的;但由于题目要求不包括一个砝码都不用的情况,所以最后找个数倒着找到下标为1就要结束;

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int N=1e2+10;
const int M=1e5+10;
int dp[N][M],a[M];
int n,sun=0,cn;
int main()
{
    scanf("%d",&n);
    int sum=0;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];//砝码的总价值
    }
    dp[0][0]=1;
    for(int i=1; i<=n; i++)
    {
        for(int j=sum; j>=0; j--)
        {
            if (dp[i-1][j])//如果 i-1 个砝码已经到达 j 质量并且标记过
            {
                dp[i][j] = 1;//选择不放第 i 个砝码
                dp[i][j + a[i]] = 1;//选择将第 i 个砝码放右边
                dp[i][abs(j - a[i])] = 1;
                //选择第 i 个砝码左边放在左边,此时 j 的质量是左右相差的绝对值
            }
            if(a[i]==j)
                dp[i][j]=1;
        }
    }
    int cnt=0;
    for(int i=sum; i>=1; i--)//找个数
    {
        if(dp[n][i]==1)
            cnt++;
    }
    printf("%d\n",cnt);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值