题目:
http://lx.lanqiao.cn/problem.page?gpid=T2893
思路都在代码里:
#include<iostream>
#include<cmath>
#define N 100001
using namespace std;
int dp[101][N];
//所有砝码质量始终不会超过100010,故可以用dp[i][j]=1表示前i-1个物品可以测量出质量j,反之则不可以
int w[101];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>w[i];
dp[0][0]=1; // 没有选物品,质量为0时也是一种重量,因此也要算进去
for(int i=;i<n;i++){
for(int j=0;j<N;j++)
if(dp[i][j]){
//若前i-1个物品可以测量出质量j
// 那么把物品i也加进去,就可以量出质量fabs(j-w[i])和质量j+w[i]
dp[i+1][j+w[i]]=dp[i+1][(int)fabs(j-w[i])]=1;
//当然,如果我们不选则第i个物品, 也可以认为前i个物品可以测量出质量j
dp[i+1][j]=1;
}
}
int ans=0;
for(int i=1;i<N;i++) //统计出所有质量
ans+=dp[n][i];
cout<<ans<<endl;
}
解dp问题的思路:
- 确定dp数组有多少个维度,每个维度可以取多少值(比如本题就是两个维度:物品种类和称量出的重量, 两个维度各取值为100和100001)
- 考虑状态转移方程是什么(比如本题的状态转移可以理解为:
若前i-1个物品可以测量出质量j
那么把物品i也加进去,就可以量出质量fabs(j-w[i])和质量j+w[i]
如果我们不选则第i个物品, 也可以认为前i个物品可以测量出质量j - 剩下的就是代码实现
最后附上比较理论、全面的dp问题解法:
https://blog.csdn.net/qq_45550375/article/details/106631418