题意:我有很多钱,要用来买债券,已知每种债券的价格和每一期可获得的利润(注意债券的价格只能为1000的倍数),而且我可以每一期把原来的债券卖掉,然后用原来的钱加上利润选择新的购买方案。已知我要一开始有多少钱和我将购买多少期债券,求出我最后有多少钱。
思路:完全背包。一开始看到债券价格为1000的倍数,我就用了
for(int j = value[i]; j <=str; j += 1000 )
……
str += ans[j - 1000];
TLE,因为str的值很大,即ans数组大小也比较大,而每处理一期的结果之前都需要memset(ans, 0, sizeof(ans)),用时较长,正确的做法是在每次将债券价格/1000,每次计算ans时循环的范围为 value[i]-str/1000,这样ans数组的大小可以开小一点,时间会减少
#include
#include
using namespace std;
int ans[600000];
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
int value[15], interest[15];
int t, mon, str, cap, d ,cur;
int i, j;
scanf("%d" ,&t);
while(t--)
{
scanf("%d%d", &str, &cap);
scanf("%d", &d);
for(i = 0; i < d; i++)
{
scanf("%d%d", &value[i], &interest[i]);
value[i] /= 1000;
}
while(cap--)
{
memset(ans, 0, sizeof(ans));
mon = str;
mon /= 1000;
for(i = 0; i < d; i++)
{
for(j = value[i]; j <= mon; j++)
{
cur = ans[j - value[i]] + interest[i];
if(cur > ans[j])
ans[j] = cur;
}
}
str += ans[mon];
}
printf("%d\n", str);
}
return 0;
}