区间DP - 石子合并
const int N = 310, INF = 0x3f3f3f3f;
int n, m[N], s[N], dp[N][N];
int main()
{
cin >> n;
for(int i = 1; i <= n; ++i)
{
cin >> m[i];
s[i + 1] = s[i] + m[i];
}
fill(dp[0], dp[0] + N * N, INF);
for(int i = n; i >= 1; --i)
{
for(int j = i; j <= n; ++j)
{
if(i == j)
dp[i][j] = 0;
else
{
for(int k = i; k < j; ++k)
dp[i][j] = min(dp[i][k] + dp[k + 1][j] + s[j + 1] - s[i], dp[i][j]);
}
}
}
cout << dp[1][n];
return 0;
}
背包应用 - 整数划分
const int N = 1010, MOD = 1e9 + 7;
int n, dp[N][N];
int main()
{
cin >> n;
for(int i = 0; i <= n; ++i)
dp[i][0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j <= n; ++j)
{
dp[i][j] = dp[i - 1][j] % MOD;
if(j >= i)
dp[i][j] = (dp[i - 1][j] + dp[i][j - i]) % MOD;
}
}
cout << dp[n][n];
return 0;
}