给出一个数字N(0<N<1000000),将N写成立方数和的形式,求出需要的最少立方数个数。
例如N=17,1+8+8 = 17,最少需要3个立方数,则输出3。
N= 28,1+1+1+1+8+8+8=28, 需要7个立方数,1+27=28,需要2个立方数,所以最少立方数为2,则输出2。
一个数字N(0<N<1000000)
最少立方数个数
28
2
/* 动态规划,设dp[n]为组成 n需要的最少立方数个数 所有差一步可以组成n的方案,求最小值加一 dp[n] = 1 + min(dp[n-1],dp[n-8],dp[n-27],...) 要求n-i*i*i>=0 */ #include<bits/stdc++.h> using namespace std; int main() { // freopen("input.txt", "r", stdin); int n, t, i; cin >> n; vector<int> dp(n + 1); dp[0] = 0; for(t = 1; t <= n; t++) { int t_min = INT_MAX; for(i = 1; i * i * i <= t; i++) { t_min = min(t_min, dp[t - i * i * i]); } dp[t] = t_min + 1; } cout << dp[n] << endl; return 0; }
/* 动态规划,设dp[n]为组成 n需要的最少立方数个数 精髓所在:找的是所有差一步可以组成n的方案,求最小值加一; dp[n] = 1 + min(dp[n-1],dp[n-8],dp[n-27],...) 要求n-i*i*i>=0 */ import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); int n = input.nextInt(); int[] dp = new int[n+1]; dp[0] = 0;dp[1] = 1; for(int i = 2;i<=n;i++){ int min = Integer.MAX_VALUE;//用于保存最小的个数 for(int j = 1;j*j*j<=i;j++){//找到最小的 min = Math.min(min,dp[i-j*j*j]); } dp[i] = min + 1; } // System.out.println(dp[n]); } }
import java.util.Scanner; /* * * https://www.nowcoder.com/practice/4bc284dc9d0144628a722eb5d1191ef3?tpId=98&&tqId=32903&rp=7&ru=/activity/oj&qru=/ta/2019test/question-ranking * * */ public class Main { public static int solution(int dp[], int n) { if (n == 1) { return 1; } dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; i++) { int min = Integer.MAX_VALUE; for (int j = 1; j * j * j <= i; j++) { if (min >= dp[i - j * j * j]) { min = dp[i - j * j * j]; } } dp[i] = min+1; } return dp[n]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int dp[] = new int[10000000]; System.out.println(solution(dp, n)); } }
#include <bits/stdc++.h> using namespace std; int main(){ int num[100]={0},n,len=0; for(int i=1;i<100;i++) num[i]=i*i*i; cin>>n; while(num[len]<=n) len++; vector<int> dp(n+1,0); for(int j=0;j<=n;j++) dp[j]=j; for(int i=2;i<len;i++) for(int j=2;j<=n;j++) if(j>=num[i]) dp[j]=min(dp[j],dp[j-num[i]]+1); cout<<dp[n]; return 0; }
#include <bits/stdc++.h> #define POW3(i) i*i*i #define MAX 1000000 + 5 #define INT_MAX 0x3F3F3F3F using namespace std; int dp[MAX]; vector<int> pow3_list; void init() { for (int i=1; POW3(i)<=MAX; i++) pow3_list.push_back(POW3(i)); memset(dp, INT_MAX, sizeof(dp)); } int main() { init(); int n; cin >> n; dp[0] = 0; for (int i=1; i<=n; i++) { for (int j=0; pow3_list[j] <= i; j++) { dp[i] = min(dp[i], dp[i-pow3_list[j]] + 1); } } cout << dp[n] << endl; return 0; }
import java.util.ArrayList; import java.util.Scanner; public class Main { static int min = Integer.MAX_VALUE; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //把小于n的立方数装进集合 ArrayList<Integer> al = new ArrayList<Integer>(); for (int i = 1; i < 100; i++) { if(Math.pow(i, 3)>n) { break; }else if (Math.pow(i, 3)==n) { System.out.println(1); return; }else { al.add((int)Math.pow(i, 3)); } } int sum = 0; dfs(n,sum,al,al.size()-1); System.out.println(min); } private static void dfs(int n, int sum, ArrayList<Integer> al,int begin) { if(n==0) {//刚好够装,判定目前的总个数(sum)是否小于最小的,是的话min等于目前的sum if(sum<min) { min = sum; } } if(n<0||sum>min) {//n小于0,不够装 return || 使用次方数个数已经超过了目前最小的次方数 return return; } for (int i = begin; i >=0; i--) { dfs(n-al.get(i), sum+1, al, i); } } } //深搜解决一切问题。。。dp我太菜了总是理解不了
N视为背包,每件物品的重量是i,其对应的价值是
问题就是求解一个容量为N, 物品数为t的完全背包问题,并且要求背包一定要装满
简化之,得
#include <bits/stdc++.h> using namespace std; const int INF = 1e9; const int maxn = 1e6 + 20; int dp[maxn]; int dp_solve(int n) { int t = (int)pow(n, 1/3.); for (int i = 1; i <= t; ++i) { for (int j = i * i * i; j <= n; ++j) { dp[j] = min(dp[j], 1 + dp[j - i * i * i]); } } printf("%d\n", dp[n]); } int main() { int n; scanf("%d", &n); dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; ++i) dp[i] = INF; dp_solve(n); return 0; }
#include <bits/stdc++.h> using namespace std; int main(){ int n; while(cin>>n){ int dp[n+1]; dp[0] = 0; dp[1] = 1; for(int i=2;i<=n;i++){ int x=1, Min=INT_MAX; while(x*x*x <= i){ Min = min(Min, dp[i-x*x*x]); x++; } dp[i] = Min + 1; } cout<<dp[n]<<endl; } return 0; }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] dp = new int[n + 1]; dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; i++) { int temp = 1, preMin = Integer.MAX_VALUE; while (temp * temp * temp <= i) { preMin = Math.min(preMin, dp[i - temp * temp * temp]); temp++; } dp[i] = preMin + 1; } System.out.println(dp[n]); } }
BFS解决
#include <iostream>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
int solve(int n) {
queue<pair<int, int> > q;
q.push(make_pair(n, 0));
vector<bool> vis(n+1, false);
vis[n] = true;
while(!q.empty()){
int num = q.front().first;
int step = q.front().second;
q.pop();
if (num == 0) return step;
for (int i = 1; ; i++) {
int a = num-i*i*i;
if (a < 0) break;
if (a == 0) return step+1;
if (!vis[a]) {
q.push(make_pair(a, step+1));
vis[a] = true;
}
}
}
return 1;
}
int main(int argc, char const *argv[])
{
int n;
cin >> n;
cout << solve(n) << endl;
return 0;
}
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int[] dp = new int[n + 1]; dp[0] = 1; dp[1] = 1; for(int i = 2; i <= n; i++){ dp[i] = Integer.MAX_VALUE; for(int j = 1; j*j*j <= i; j++){ if(j*j*j == i){ dp[i] = 1; }else if(dp[j*j*j] > 0 && dp[i - j*j*j] > 0){ dp[i] = Math.min(dp[i], dp[j*j*j] + dp[i - j*j*j]); } } } System.out.println(dp[n]); } }
package main import ( "fmt" "math" ) func counter(num int) { var dp = make([]int, num + 1) dp[0] = 0 dp[1] = 1 var minInit = math.MaxInt64 for i := 2; i <= num; i++ { var j int = 1 var min int = minInit for j*j*j <= i { if dp[i-j*j*j] < min { min = dp[i-j*j*j] } j++ } dp[i] = min + 1 } fmt.Print(dp[num]) } func main() { num := 0 n, _ := fmt.Scan(&num) if n == 0 { fmt.Println(0) } else { fmt.Sprintf("%d", num) counter(num) } }
import java.util.*; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] dp = new int[n+1]; dp[0] = 0; for (int i = 1;i <= n;i++) { int min = Integer.MAX_VALUE; for (int j = 1;j*j*j <= i; j++) { min = Math.min(min, dp[i-j*j*j]); } dp[i] = 1 + min; } System.out.println(dp[n]); } }
public class Test { public static void main(String[] args) { Random random = new Random(); System.out.println(getInt(random.nextInt(1000000))); } public static int getInt(int N){ System.out.println("N = " + N); int re = 0; int secondFor = 100; for (int i = 1; i < 101; i++) { for (int j = secondFor; j > 0; j--) { if (j*j*j <= N){ N = N - j*j*j; secondFor = j; System.out.println("第" + i + "次做减法,j = " + j + ",j*j*j = " + j*j*j + ",N还剩:" + N ); break; } } if (N == 0){ re = i; break; } } return re; } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[100]; for(int i=1;i<100;i++) arr[i] = i*i*i; int[] dp = new int[n+1]; dp[1] = 1; for(int i=2;i<=n;i++){ for(int j=99;j>0;j--){ if(i==arr[j]){ dp[i] = 1; break; }else if(i>arr[j]){ int x = 1 + dp[i-arr[j]]; if(dp[i]==0) dp[i] = x; else dp[i] = Math.min(dp[i],x); } } } System.out.println(dp[n]); } }