将所有可能的取左取右的取法存入数组中以01的形式区分
#include <iostream>
#include <cmath>
#include <vector>
#include<algorithm>
using namespace std;
int C(int n,int m){ //计算排列数
if(m==0 || m == n) return 1;
return C(n-1,m)+C(n-1,m-1);
}
void F(vector<int>&arr,vector<vector<int>>&dp1,int m, int *p,int num){ int k=0;
sort(arr.begin(),arr.end());
do{
for(int t=0;t<m;t++){
dp1[k][t]=arr[t];
}
if(k<num) k++;
}
while(next_permutation(p,p+m));
}
int fun1(int i,int j,vector<vector<int>> a,int m){ //第i+1行左边取j+1次的情况的最大值
int num=C(m,j+1); //计算组合数
vector<vector<int>>dp1(num, vector<int>(m));//记录取法
vector<int>arr(m);
for(int r=0;r<j+1;r++){
arr[r]=1;
}
int *p=&arr[0];
F(arr,dp1,m,p,num); //给出所有de取法
int max=0;
for(int d=0;d<num;d++){//确定取法
int left=0,right=m-1;
int sum=0;
for(int h=0;h<m;h++){
if(dp1[d][h]==1){ //取左
sum+=a[i][left]*pow(2,h+1);
left++;
}
if(dp1[d][h]==0){
sum+=a[i][right]*pow(2,h+1);
right--;
}
}
if(sum>max){
max=sum;
}
}
return max;
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
}
}
vector<vector<int>>dp(n, vector<int>(m));
int total=0;
for (int i = 0; i < n; i++) {//行数
int max=0;
for (int j = 0; j < m; j++) {//左边取的数
dp[i][j]=fun1(i,j,a,m); //左边取某个数得到的的最大值
if(dp[i][j]>max){
max=dp[i][j];
}
}
total+=max;
}
cout<<total;
}

被折叠的 条评论
为什么被折叠?



