2022-3-1

砝码称重

问题描述

你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1​,W2​,⋅⋅⋅,WN​。

请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边

输入格式

输入的第一行包含一个整数 N。

第二行包含 N 个整数 W1​,W2​,W3​,⋅⋅⋅,WN​。

输出格式

输出一个整数代表答案。

样例输入

3
1 4 6

样例输出

10

样例说明

能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11​

1 = 1;

2=6−4(天平一边放 6,另一边放 4);​

3 = 4 − 1;

4 = 4;

5 = 6 − 1;​

6 = 6;

7 = 1 + 6;

9 = 4 + 6 − 1;

10 = 4 + 6;

11 = 1 + 4 + 6。

评测用例规模与约定

对于 50%的评测用例,1≤N≤15。

对于所有评测用例,1≤N≤100,N​个砝码总重不超过 100000

说明:dp[0][0]=1表示:0个砝码(=1)能称出重量0

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
  int dp[105][100000]={0},n,w[105],sum=0,ans=0;
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>w[i];
    sum+=w[i];//砝码总重量,称不出比总重量还重的重量
  }
  dp[0][0]=1;
  for(int i=1;i<=n;i++){
    for(int j=0;j<=sum;j++){
      //重量没有负数,因此用绝对值表示(例如:2-4=-2取绝对值后相当于能称出质量2)
      dp[i][j]=max(dp[i-1][j],max(dp[i-1][j+w[i]],dp[i-1][abs(j-w[i])]));
      //dp[0][j](j>0)=0,dp[i][0]=1,若dp[i-1][j]=1,则dp[i][j]=1;否则就加入
    }
  }
  for(int i=1;i<=sum;i++){//重量0不算一种情况
    if(dp[n][i]) ans++;//用n个砝码能(dp=1)否(dp=0)称出重量i
  }
  cout<<ans<<endl;
  return 0;
}

杨辉三角形

题目描述

下面的图形是著名的杨辉三角形:

如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,⋯

给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数

输入描述

输入一个整数 N。

输出描述

输出一个整数代表答案。

示例 1

输入

6

输出

13

评测用例规模与约定

对于 20% 的评测用例,1≤N≤10​; 对于所有评测用例, 1≤N≤1e9。

!!可以发现第一次出现的数一定都在左边!!

#include <iostream>
using namespace std;

//杨辉三角
typedef long long ll;
ll n;//n<=1e9
ll C(ll a,ll b){//求组合数Cab
  ll res=1;//res也可能很大!!!
  for(ll i=a,j=1;j<=b;i--,j++){
    res=res*i/j;
    if(res>n) return res;
  }
  return res;
}
int main()
{
  cin>>n;
  for(int k=16;k>=0;k--){//从第16列开始二分查找,先找所在列
    ll l=2*k,r=max(n,l),mid;//mid:所在行
    while(l<=r){
      mid=(r+l)/2;
      ll c=C(mid,k);
      if(c==n) break;
      else if(c>n) r=mid-1;
      else l=mid+1;
    }
    if(C(mid,k)==n){
      cout<<(mid+1)*mid/2+k+1<<endl;//第0行1个数,开始
      break;
    }
  }
  // n=1e9;
  // for(ll i=1;;i++){
  //   if(C(2*i,i)>n){
  //     cout<<i<<endl;
  //     break;
  //   } 
  // }算出n最多出现在第16列
  return 0;
}

 坑坑坑:最好这里面数据类型都用long long,要不连哪里错了都找不到!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值