C++ -動態規劃
阿新 • • 發佈:2018-12-09
1、鋼材切割
程式碼1思路:
將鋼材切割問題優化為:
- 鋼材長度n<=10
- 鋼材長度n>10
對於n<=10,可以遍歷迭代解決;對於n>10,可以分段切割,每次切割i=1,2,。。。10十種情況;
此法有個缺點,n較大時迭代時間長,n=30時,計算時長需要37s。
#include <iostream> #include <string> #include <time.h> using namespace std; int p[11] = { 0,1,5,8,9,10,17,17,20,24,30 }; int max(int a, int b) { if (a >= b) return a; else return b; } int fun(int *p, int n) { if (n == 0) return 0; int q = 0; if (n <= 10) { for (int i = 1; i <= n; i++) q = max(q, p[i] + fun(p,n-i)); } else { for(int i=1;i<=10;i++) q = max(q, p[i] + fun(p, n - i)); } return q; } int main() { int n; while (cin >> n) { clock_t start, end; start = clock(); cout << "最佳收益:" << fun(p,n) << endl; end = clock(); cout << "time is " << (double)(end - start) / CLOCKS_PER_SEC << endl; } }
程式碼1優化:
可以維護一張最優值表,減少一些重複的迭代(首先計算n=1-10的最佳值,之後就開始維護一張表p,會發現計算速度越來越快)
#include <iostream> #include <string> #include <time.h> using namespace std; int a[11]= { 0,1,5,8,9,10,17,17,20,24,30 };//初值表 int p[1000] = {0};//最優表 int max(int a, int b) { if (a >= b) return a; else return b; } //求解n=1-10的最優質 int max_val(int *p,int n) { int q = 0; for (int i = 1; i <= n; i++) { q = max(q, p[i] + max_val(p, n - i)); } if (q > a[n]) p[n] = q; return q; } int fun(int *p, int n) { if (n == 0) return 0; if (p[n] != 0) return p[n];//如果已經求解,那麼直接返回值(n<=10已經求解) int q = 0; for (int i = 1; i < n; i++) { q = max(q, p[i] + fun(p, n - i)); } if (p[n] < q) p[n] = q; return q; } int main() { int n; //求解n的1-10時候的最小值 for (int i = 1; i <= 10; i++) max_val(a, i); for (int i = 1; i <= 10; i++) p[i] = a[i];//賦值 while (cin >> n) { clock_t start, end; start = clock(); cout << "最佳收益:" << fun(p,n) << endl; end = clock(); cout << "time is " << (double)(end - start) / CLOCKS_PER_SEC << endl; } }
2、軍訓
#include <iostream> #include <string> #include <vector> using namespace std; int main() { int N; cin >> N; while (N--) { int num; cin >> num; int left = num; vector<bool> v(num + 1, false); while (1) { if (left > 3)//排除2 { int count = 0; for (int i = 1; i <= num; i++) { if (v[i] == false) { count++; } if (count == 2) { v[i] = true; count = 0; left--; } } } if (left <= 3) break; if (left > 3)//排除3 { int count = 0; for (int i = 1; i <= num; i++) { if (v[i] == false) { count++; } if (count == 3) { v[i] = true; count = 0; left--; } } } if (left <= 3) break; } for (int i = 1; i <= num; i++) if (v[i] == false) cout << i << " "; cout << endl; } //getchar(); //while (1); return 0; }