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

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

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

      P5322 [BJOI2019] 排兵布陣

      題目傳送門

      博客傳送門

      我們瀏覽一遍測試點,發現了一個 \(s=1\) 的特殊性質。先考慮這一性質。

      \(s=1\)特殊性質

      如果我們當前第 \(i\) 座城市的兵力數量足夠時,添加兵力顯然不優。而如果兵力不夠,我們的最優策略挺顯然的,要么添加兵力使其恰好足夠,要么干脆就不要這個城市。

      換句話說,我們對一個城市的決策只有選與不選兩種,選的話需要花費一定的體積,同時獲得一定的價值。

      聽我這么一描述,是不是感覺這就是個很板的01背包?對的對的,這個部分分就是個01背包板子……忘記01背包的可以移步01背包基礎

      而那個兵力限制 \(m\),往這個方向上考慮,其實就是個背包最大容量 \(V\)

      特殊性質代碼也貼在這里,希望有助于大家理解。

      P5322特殊性質
      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      
      inline int read(){
      	int x=0,f=1;char c=getchar();
      	while(c<48){
      		if(c=='-') f=-1;
      		c=getchar();
      	}
      	while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();
      	return x*f;
      }
      
      const int N=120;
      const int M=2e4+4;
      int S,n,m,w[N],v[N],dp[M];
      
      signed main(){
      	S=read(),n=read(),m=read();
      	int W=m;
      	//不同于我當時的博文,這里的w數組是代價,v數組是價值 
      	for(int i=1;i<=n;i++){
      		int x=read();
      		//根據題意,第i座城市恰巧被占領的兵力是2*a[i]+1 
      		w[i]=((x<<1)|1),v[i]=i;
      	}
      	//01背包模版 
      	for(int i=1;i<=n;i++){
      		for(int j=W;j>=w[i];j--){
      			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
      		}
      	}
      	int ans=dp[m];
      	printf("%lld",ans);
      	return 0;
      }
      

      正解

      那既然這個部分分是個背包dp,我們合理猜測本題也是個dp,搞不好還是背包dp。

      考慮分組背包。簡單來說,既然對決是獨立的,我們對于某座城池,首先可以將 \(s\) 個人的駐守兵力從小到大排序。記排序后的數組為 \(b\)

      接下來的過程類似于你做題時拿部分分。

      P5322_1_1

      P5322_2_1

      對于某個城市 \(i\),因為 \(b_1 \le b_2 \le \cdots b_s\) ,所以如果我們現在的駐扎兵力剛好可以拿下 \(b_j\) 的話,那它一定能且只能拿下 \(b_1,b_2,\cdots,b_j\)

      所以我們拆物品方法有所不同:對于\(i\) 城市兵力第 \(j\) 小的那個對應得物品,我們讓它的體積是 \(2*b_j+1\),價值是 \(j \times i\),如上圖所示。

      (類似于你拿部分分,除非特殊性質,否則你拿到越靠后的分,用的時間一般越長,但拿到的分值也會越高。而且你能解決后面的部分分,也就能解決前面的部分分)

      就像你做題的時候,一道題目只會有一個得分,對于 \(i\) 城市,貢獻只能有一個,所以這個分組背包的組就是每個城市,里面的物品就是剛才拆出來的 \(s\) 個。我們只能選擇一個物品的價值作為這個城市的最終貢獻。

      總之分析到這里,本題就是個很板的背包dp,僅此而已。

      代碼:

      P5322
      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      
      inline int read(){
      	int x=0,f=1;char c=getchar();
      	while(c<48){
      		if(c=='-') f=-1;
      		c=getchar();
      	}
      	while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();
      	return x*f;
      }
      
      const int N=120;
      const int M=2e4+4;
      int S,n,m,w[N],v[N],dp[M],a[N][N],b[N],W[N][N],V[N][N],DP[N][M];
      
      signed main(){
      	S=read(),n=read(),m=read();
      	for(int i=1;i<=S;i++){
      		for(int j=1;j<=n;j++){
      			a[i][j]=read();
      		}
      	}
      	//拆分物品 
      	for(int i=1;i<=n;i++){
      		for(int j=1;j<=S;j++){
      			b[j]=a[j][i];
      		}
      		sort(b+1,b+S+1);
      		for(int j=1;j<=S;j++){
      			W[i][j]=2*b[j]+1,V[i][j]=i*j;
      		}
      	}
      	//分組背包 
      	for(int i=1;i<=n;i++){
      		for(int j=1;j<=m;j++){
      			for(int k=0;k<=S;k++){
      				//k=0時的物品價值是0,代價是0,相當于根本不要i城市的情況 
      				if(j>=W[i][k]){
      					DP[i][j]=max(DP[i][j],DP[i-1][j-W[i][k]]+V[i][k]);
      				}
      			}
      		}
      	}
      	int ans=DP[n][m];
      	printf("%lld",ans);
      	return 0;
      }
      
      posted @ 2025-10-28 19:51  qwqSW  閱讀(9)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 青青青爽在线视频观看| 亚洲精品色国语对白在线| 性欧美videofree高清精品| 亚洲另类激情专区小说婷婷久| 精品人妻无码一区二区三区性| 成人av天堂网在线观看| 龙南县| 亚洲国产成人精品女人久| av午夜福利一片免费看久久| 国产一区二区不卡在线| 国产欧美亚洲精品a第一页| 偷偷做久久久久免费网站| 丁香五月天综合缴情网| 国产欧美精品一区二区三区| 熟女国产精品一区二区三| 午夜男女爽爽影院在线| 国产成人午夜福利院| 国产成人精品18| 日本欧美一区二区免费视频 | 亚洲一二三区精品与老人| 亚洲熟妇自偷自拍另欧美| 成人免费xxxxx在线观看| 久久久久国产精品人妻| 九九热免费在线观看视频| 国产69精品久久久久99尤物| 少妇高清一区二区免费看| 久久婷婷成人综合色| 人妻另类 专区 欧美 制服| 东京热加勒比无码少妇| 欧美牲交a欧美牲交aⅴ图片| 久久亚洲精品11p| 国产亚洲精品福利在线无卡一| 国产精品第一页中文字幕| 亚洲婷婷综合色高清在线| 人妻夜夜添夜夜无码av| 国产一区二区三区禁18| 人人人澡人人肉久久精品| 噜噜久久噜噜久久鬼88| 色综合久久天天综线观看| 久久99精品国产99久久6尤物| 青青草成人免费自拍视频|