这题,给你N钱,求投资的最小块。N钱肯定会用完的,因为最小是1嘛。。。
开始就是往背包上想,多重背包转换为多重背包,然后仨循环,绝对超时的,然后BTW一提醒,我想起来完全背包的另一个版本了,类似01的只不过循环从1开始了,想了想,写了写,居然搞出来了T T。。
打表的时候,价值的表存的是钱x下用的最少的块数,类似一般背包中的v数组。w数组就是平方啦,然后就完全背包就好啦。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
using namespace std;
const int MAX = 60010;
int dp[MAX];
int num[MAX];
int w[300];
int v[MAX];
void init()
{
dp[0] = 0;
for(int i=1; i<=60000; i++)
dp[i] = v[i] = i;
for(int i=0; i<300; i++)
w[i] = i*i;
for(int i=1; i<300; i++)
for(int k=1; k*i*i<MAX; k++)
v[k*i*i] = min(v[k*i*i],k);
}
int main()
{
int n;
init();
for(int i=1; i<300; i++)
for(int k=w[i]; k<=60000; k++)
dp[k] = min( dp[k],dp[k-w[i]]+v[w[i]] );
while( ~scanf("%d",&n) )
{
printf("%d\n",dp[n]);
}
return 0;
}