noip刷題筆記1
本人是個oi蒟蒻,如果有什麼不對的地方望指正
這次我做了幾道動態規劃題,留個記錄
1.筷子(傳送門:http://www.caioj.cn/problem.php?id=1077)
首先這一題我們先定義一個陣列dp[i][j],表示前i只筷子裡挑出j雙,每雙筷子差的平方的和的最小值
然後將筷子長度從小到大排序.因為給出的筷子長度是亂的,如果排序能保證每次選取鄰近兩根的筷子比選取不臨近的兩跟筷子的差要小,不排序則要跳著選,dp方程不好寫
接著初始化dp陣列,再列舉i,j,若不選第i根,dp[i][j]=dp[i-1][j],若選擇,則需要再列舉一個m和i配對,dp[i][j]=min(dp[i][j],dp[m-1][j-1]+(t[i]-t[m])²)
程式碼如下:
#include <iostream>
#include <algorithm>
using namespace std;
int n,k;
int dp[101][61];//dp[i][j]表示前i箇中選出j雙的差平方最小值
const int inf=1<<30;
int t[101];
int main() {
cin >> n >> k;
k+=3;
for(int i=1;i<=n;i++) cin >> t[i];
if(k*2>n) {
cout << -1 << endl;
return 0;
}
sort(t+1,t+n+1);//排序是為了保證選擇相鄰的一雙筷子差值的平方最小
fill(dp[0],dp[0]+101*61,inf);
for(int i=0;i<=n;i++) dp[i][0]=0;//不組成一對
for(int i=1;i<=n;i++) {
for(int j=1;j<=k;j++) {//j雙筷子
dp[i][j]=dp[i-1][j];//第I根不選
for(int m=1;m<i;m++) {//選另外一個並組成差平方最小的
dp[i][j]=min(dp[i][j],dp[m-1][j-1]+(t[i]-t[m])*(t[i]-t[m]));
}
}
}
cout << dp[n][k] << endl;
return 0;
}
2.不重疊線段(傳送門:http://www.caioj.cn/problem.php?id=1078)
先定義一個陣列dp[i]表示覆蓋區間[1,i]最大覆蓋數字的數量
然後將線段的起點從小到大排序,方便後面dp
列舉每條線段,將這條線段的終點對應的覆蓋數與這條線段起點前對應的覆蓋數加上線段長度作比較,若終點覆蓋數更小則更新到較大值
然後將這條線段後的所有端點對應的覆蓋數更新為這個最大值
程式碼如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
struct node {
int x,y;
};
vector<node> v;
int dp[2002]={0};//dp[i]使用某些線段,覆蓋區間[1,n],最多可以覆蓋多少個數字
bool cmp(node a,node b) {
return a.x<b.x;
}
int main() {
cin >> n;
for(int i=1;i<=n;i++) {
int a,b;
cin >> a >> b;
a++,b++;
if(a>b) swap(a,b);//若線段是反的就挑頭
v.push_back((node){a,b});
}
sort(v.begin(),v.end(),cmp);//將每條線段按起點值從小到大排序,方便後面dp
for(int i=0;i<v.size();i++) {
if(dp[v[i].x-1]+(v[i].y-v[i].x+1)>dp[v[i].y]) {
dp[v[i].y]=dp[v[i].x-1]+(v[i].y-v[i].x+1);//若這條線段前已經覆蓋的個數加上線段覆蓋長度大於當前的這條線段覆蓋個數,更新當前值
for(int j=v[i].y+1;j<=2001;j++) {//更新後面位置的最大覆蓋值
dp[j]=max(dp[j],dp[v[i].y]);
if(dp[j]>dp[v[i].y]) break;//更新完畢
}
}
}
cout << dp[2001] << endl;
return 0;
}
相關文章
- 刷題筆記02筆記
- 刷題筆記03筆記
- LeetCode 刷題筆記LeetCode筆記
- leetcode刷題筆記LeetCode筆記
- leetcode刷題筆記605LeetCode筆記
- ctfshow刷題記錄-cry方向-1
- ctfshow刷題記錄-社工篇-1
- 劍指Offer系列刷題筆記彙總筆記
- leetcode刷題筆記(3)(python)LeetCode筆記Python
- (刷題筆記)軟考中級資料庫 上午題筆記資料庫
- LeetCode刷題記錄——day1LeetCode
- ✏️ JavaScript版 | 10大專題 | 劍指offer刷題筆記 ✏️JavaScript筆記
- 力扣刷題Python筆記:括號生成力扣Python筆記
- Leetcode171-190刷題筆記(非困難題)LeetCode筆記
- 刷前端面經筆記(十)前端筆記
- 刷前端面經筆記(七)前端筆記
- 刷前端面經筆記(九)前端筆記
- 刷前端面經筆記(八)前端筆記
- 刷前端面經筆記(一)前端筆記
- 刷前端面經筆記(二)前端筆記
- 刷前端面經筆記(三)前端筆記
- 刷前端面經筆記(四)前端筆記
- 刷題筆記:樹的前序、中序、後序遍歷筆記
- 力扣刷題筆記:207. 課程表力扣筆記
- 面試刷題偶有記錄面試
- 刷題記錄:劍指offer+遇到的筆試題+LeetCode筆試LeetCode
- <題解>「LibreOJ NOIP Round #1」序列劃分
- 牛客刷題筆記--(java基礎301-400)筆記Java
- [LeetCode刷題筆記] 關於LeetCode的前言LeetCode筆記
- 【刷題筆記】LeetCode-53 最大子陣列和筆記LeetCode陣列
- LeetCode刷題記錄LeetCode
- leetcode刷題--Number of 1 BitsLeetCode
- 【LeetCode刷題筆記-33 649:Dota2 參議院】LeetCode筆記
- noip day1 2
- 牛客網刷題(純java題型 1~30題)Java
- 筆記1筆記
- 刷題記錄(C語言)01C語言
- 【刷題打卡】day1 - 字串string字串