<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      背包

      背包 \(DP\)

      今日 \(2025.10.23\),距 \(CSP\) \(9\) 天,\(NOIP\) \(37\)

      昨天被線性 \(DP\) 爆切了,但確實學到一些巧妙的東西,然后就要開始今天的背包 \(DP\) 受虐學習了

      今天的背包大部分都用了滾動數組優化空間,可能對初學者不太友好

      01背包

      luogu 板題 P2871 [USACO07DEC] Charm Bracelet S

      #include<bits/stdc++.h>
      using namespace std;
      const int N=12885;
      int n,m,a,b,f[N];
      int main(){
      	cin>>n>>m;
      	for(int i=1;i<=n;i++){
      		cin>>a>>b;
      		for(int j=m;j>=a;j--){
      			f[j]=max(f[j],f[j-a]+b);
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      luogu P1048 [NOIP 2005 普及組] 采藥

      #include<bits/stdc++.h>
      using namespace std;
      const int M=1005;
      int n,m,f[M],a,b;
      int main(){
      	cin>>m>>n;
      	for(int i=1;i<=n;i++){
      		cin>>a>>b;
      		for(int j=m;j>=a;j--){
      			f[j]=max(f[j],f[j-a]+b);
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      luogu P1507 NASA的食物計劃

      雙限制 \(01\) 背包,只需在枚舉狀態時多加一維限制即可,復雜度:\(O(n^3)\)

      #include<bits/stdc++.h>
      using namespace std;
      const int M=404;
      int n,H,T,h,t,w,f[M][M];
      int main(){
      	cin>>H>>T>>n;
      	for(int i=1;i<=n;i++){
      		cin>>h>>t>>w;
      		for(int j=H;j>=h;j--){
      			for(int k=T;k>=t;k--){
      				f[j][k]=max(f[j][k],f[j-h][k-t]+w);
      			}
      		}
      	}
      	cout<<f[H][T];
      	return 0;
      }
      

      luogu P1855 榨取kkksc03

      這是雙限制方案數 \(DP\),本題可以把價值都當作 \(1\),就和上一題一樣了

      #include<bits/stdc++.h>
      using namespace std;
      const int N=205;
      int n,M,T,m,t,f[N][N];
      int main(){
      	cin>>n>>M>>T;
      	for(int i=1;i<=n;i++){
      		cin>>m>>t;
      		for(int j=M;j>=m;j--){
      			for(int k=T;k>=t;k--){
      				f[j][k]=max(f[j][k],f[j-m][k-t]+1);
      			}
      		}
      	}
      	cout<<f[M][T];
      	return 0;
      }
      

      完全背包

      要注意,完全背包是滾動數組優化的 \(DP\) 中最特殊的一種。\(01\),分組,多重背包開滾動數組時,容量限制要 從大到小 遍歷,以此保證同一種物品 不會選多次,而完全背包不同,每種物品可選 無數次,所以可以由之前選過當前物品的狀態轉移過來,所以,容量限制要 從小到大就算不開滾動數組,完全背包的容量也要從小到大遍歷

      P1616 板題 瘋狂的采藥

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e7+5;
      int n,m,a;
      long long f[N],b;
      int main(){
      	cin>>m>>n;
      	for(int i=1;i<=n;i++){
      		cin>>a>>b;
      		for(int j=a;j<=m;j++){
      			f[j]=max(f[j],f[j-a]+b);
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      分組背包

      luogu 板題 P1757 通天之分組背包

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1005;
      int n,m,a[N],b[N],c[N],f[N],cnt;
      vector<int>v[N];
      int main(){
      	cin>>m>>n;
      	for(int i=1;i<=n;i++){
      		cin>>a[i]>>b[i]>>c[i];
      		cnt=max(cnt,c[i]);
      		v[c[i]].push_back(i);
      	}
      	for(int i=1;i<=cnt;i++){
      		for(int j=m;j;j--){
      			for(int k=0;k<v[i].size();k++){
      				int x=v[i][k];
      				if(j>=a[x]) f[j]=max(f[j],f[j-a[x]]+b[x]);
      			}
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      容量更新背包

      對,我給它起名叫做這個,具體為什么看例題就理解原因了

      luogu P1853 投資的最大效益

      本題你會發現,每一年的總資產會增加,然后第二年的 背包容量 就更新成了這個 新的總資產本題也是完全背包

      階段:以每年為階段

      狀態:\(f_{i}\) 表示花 \(i\) 元買股票所能獲得的最大利潤(注意,本題對于 \(100%\) 的數據有特殊性質,總資產和價錢都是 \(1000\) 的倍數,所以,為了節約空間,可以給總資產和價格都除以 \(1000\),這樣不僅節省空間,也節約了時間)

      轉移:和完全背包一模一樣

      每個階段結束后,要更新容量(也就是題中的總資產),最后的答案也是總資產

      #include<bits/stdc++.h>
      using namespace std;
      const int N=45,M=1e6+5;
      int s,n,d,a[N],b[N],f[M],ans;
      int main(){
      	cin>>s>>n>>d;
      	for(int i=1;i<=d;i++) cin>>a[i]>>b[i];
      	for(int i=1;i<=n;i++){
      		int m=s/1000;
      		for(int j=1;j<=d;j++){
      			for(int k=a[j]/1000;k<=m;k++){
      				f[k]=max(f[k],f[k-a[j]/1000]+b[j]);
      			}
      		}
      		s+=f[m];//更新總資產
      	}
      	cout<<s;
      	return 0;
      }
      

      luogu P5662 [CSP-J2019] 紀念品

      本題和上題一模一樣,放到這里,供練習

      #include<bits/stdc++.h>
      using namespace std;
      const int N=105;
      int n,m,v,f[10005],a[N][N];
      int main(){
      	cin>>n>>m>>v;
      	for(int i=1;i<=n;i++){
      		for(int j=1;j<=m;j++){
      			cin>>a[i][j];
      		}
      	}
      	for(int i=1;i<n;i++){
      		memset(f,0,sizeof(f));
      		for(int j=1;j<=m;j++){
      			for(int k=a[i][j];k<=v;k++){
      				f[k]=max(f[k],f[k-a[i][j]]+a[i+1][j]-a[i][j]);
      			}
      		}
      		v+=f[v];
      	}
      	cout<<v;
      	return 0;
      }
      

      紙幣三題

      其實不能算是單獨一類一種背包,這所以列出一類,是為了說明 \(DP\)以不同標準作為階段的區別(三道題都是 完全背包 類的)

      P2842 紙幣問題 1

      本題是最優性問題,并且本題以 紙幣種類 或者 目標面額 為階段都可以

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1005,M=1e4+5;
      int n,m,a[N],f[M];
      int main(){
      	memset(f,0x3f,sizeof(f));
      	cin>>n>>m;
      	for(int i=1;i<=n;i++) cin>>a[i];
      	f[0]=0;
      	for(int i=1;i<=m;i++){
      		for(int j=1;j<=n;j++){
      			if(i>=a[j]) f[i]=min(f[i],f[i-a[j]]+1);
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      P2840 紙幣問題 2

      本題要求的是恰好湊出目標金額的紙幣 排列數

      這就要注意了,排列是具有有序性的,例如,我有 \(1\)元、\(2\) 元的面額,要湊 \(3\) 元的面額,那么 \(1+2\)\(2+1\) 算兩種方案

      所以,階段就不能隨便定了,但我們可以確定的是,階段只可能是 組合出的面額 或者 紙幣種類,接著,分別假設

      如果以 紙幣種類 作為階段,組合出的面額 作為狀態,不難發現,求出的方案中的紙幣是按紙幣編號排列的,也就是說,上面的例子就只能得到 \(1+2\) 一種方案,缺少了 \(2+1\) 的方案,所以這種不可取

      那么,就以 組合出的面額 為階段,然后遍歷每種紙幣,不難發現,對于上面的例子,就可以湊出 \(1+2\)\(2+1\) 兩種方案了,如果還不懂,就看代碼吧

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1005,M=1e4+5,mod=1e9+7;
      int n,m,a[N],f[M];
      int main(){
      	cin>>n>>m;
      	for(int i=1;i<=n;i++) cin>>a[i];
      	f[0]=1;
      	for(int i=1;i<=m;i++){
      		for(int j=1;j<=n;j++){
      			if(i>=a[j]) f[i]=(f[i]+f[i-a[j]])%mod;
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      luogu P2834 紙幣問題 3

      這道題要求組合數,然后不難發現,如果以紙幣種類為階段,求出的恰好就是組合數,和上一題的階段不同求出的方案數代表的意義就不同(對于計數類 \(DP\) 是這樣的)

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1005,M=1e4+5,mod=1e9+7;
      int n,m,a[N],f[M];
      int main(){
      	cin>>n>>m;
      	for(int i=1;i<=n;i++) cin>>a[i];
      	f[0]=1;
      	for(int i=1;i<=n;i++){
      		for(int j=a[i];j<=m;j++){
      			f[j]=(f[j]+f[j-a[i]])%mod;
      		}
      	}
      	cout<<f[m];
      	return 0;
      }
      

      好了,今天先到這里,筆者還得學校內的高考課。對了,還有一件事,在我的同學 \(hwh\) 的建議下,筆者準備寫寫自己平時獨立推出的數學方面的東西,可能會與高考課的內容有關,或者是筆者做某些題時引起的思考,或者是一些基礎的公式推導,個人感覺筆者的數學比 \(OI\) 好一些,好了,敬請期待吧!

      posted @ 2025-10-23 21:50  czh(抽紙盒)  閱讀(3)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品国产99国产精品澳门| 日韩av一中美av一中文字慕| 天天做天天爱夜夜爽导航| 国产成人最新三级在线视频| 亚洲精品色在线网站| 在线观看中文字幕国产码| 少妇爽到呻吟的视频| 亚洲乱码日产精品bd在线| 亚洲人成网网址在线看| 精品人妻少妇嫩草av专区| 国产午夜一区二区在线观看| 最新高清无码专区| 中文字幕av日韩有码| 亚洲精品不卡av在线播放 | 亚洲天堂av日韩精品| 国产精品护士| 亚洲一区二区无码影院| 亚洲色大成网站WWW永久网站| 免费无遮挡无码永久在线观看视频| 亚洲一区二区三区在线播放无码| 色综合色国产热无码一| 日韩av裸体在线播放| 日本高清在线播放一区二区三区| 国产无遮挡免费视频免费| 日韩久久久久久中文人妻| 久青草国产在视频在线观看| 国产精品国产精品国产精品| 国产va免费精品观看| 国产日韩综合av在线| 性欧美vr高清极品| 内射老阿姨1区2区3区4区| 国产中文一区卡二区不卡| 人人妻人人添人人爽日韩欧美| 南康市| 国产一区二区av天堂热| 熟妇女人妻丰满少妇中文字幕| 宜丰县| 一区二区三区无码免费看| 中文字幕日韩熟女av| 国产成人MV视频在线观看| 五月花成人网|