原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2546
题目大意:
余额>=5,就可消费。否则,不能。(一开始又理解错了)
状态转移方程:
在保证余额>=5的情况下:dp[ j ] = max(dp[ j ], dp[ j - jg[i] ]+jg[ i ]);
(二维:if (j>=jg[i]&&(dp[i - 1][j - jg[i]] + jg[i])>=dp[i - 1][j])
{
dp[i][j] = dp[i - 1][j - jg[i]] + jg[i];
}
else dp[i][j] = dp[i - 1][j];)
因为已经保证余额>=5且最接近5,最后再买一道最贵的菜,便是最少余额。即money-dp[money-5]-最贵的菜的价格
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1000 + 10;
int jg[N], dp[N];
int main()
{
int n;
while (cin >> n&&n)
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
cin >> jg[i];
sort(jg + 1, jg + 1 + n);
int money;
cin >> money;
if (money < 5)
{
cout << money << endl;
continue;
}
for (int i = 1; i < n; i++)
{
for (int j = money-5; j >=jg[i]; j--)
{
dp[j] = max(dp[j], dp[j - jg[i]]+jg[i]);
}
}
cout << money - dp[money-5]-jg[n] << endl;
//for (int i = 0; i <= money; i++)
// cout << dp[i] << " ";
}
return 0;
}
顺便二维代码也给出:
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N = 1000 + 2;
int jg[N];
int dp[N][N];
int main()
{
int n;
while (cin >> n&&n)
{
for (int i = 1; i <= n; i++)
{
cin >> jg[i];
}
sort(jg + 1, jg + n + 1);
memset(dp, 0, sizeof(dp));
int money;
cin >> money;
if (money < 5)
{
cout << money << endl;
continue;
}
for (int i = 1; i < n; i++)
{
for (int j = money-5; j>=1; j--)
{
if (j>=jg[i]&&(dp[i - 1][j - jg[i]] + jg[i])>=dp[i - 1][j])
{
dp[i][j] = dp[i - 1][j - jg[i]] + jg[i];
}
else dp[i][j] = dp[i - 1][j];
}
}
cout << money-dp[n-1][money-5]-jg[n] << endl;
}
return 0;
}