砝码称重
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
cin >> n;
int w[n+5], m=0;
for(int i=1;i<=n;i++)
{
cin >> w[i];
m+=w[i];
}
bool f[n+5][2*m+5];
memset(f,0,sizeof f);
int B = m; // -m--1 0 1-m 对应 0-m-1 m m+1-2m
f[0][B] = true;
for(int i=1;i<=n;i++)
{
for(int j=-m;j<=m;j++)
{
f[i][j+B] = f[i-1][j+B]; // 不放
if (j - w[i] >= -m) f[i][j + B] |= f[i - 1][j - w[i] + B]; // +
if (j + w[i] <= m) f[i][j + B] |= f[i - 1][j + w[i] + B]; // -
}
}
int ans = 0;
for(int i=1;i<=m;i++)
if(f[n][i])
ans++;
cout << ans << endl;
return 0;
}
分析:
dp
感觉还是很难想①是要认识到dp,第i个砝码可以不放、放负的、放正的,而且只和第i-1个砝码有关。②是f行列表示,最开始我想的是n个砝码,3中选择,值是能表示的数字,但发现要额外存前一个具体数字,但发现不行。看y总,行列分别表示n个砝码-m-m数字(m为最大值),然后值是布尔类型,表示能否用前i个砝码做到这个数字③是偏移量,因为涉及到负数
没做出来原因:
想不到,根本没往dp方向想