題目描述
有乙個n*m的矩陣,恰好改變其中乙個數變成給定的常數p,使得改變後的這個矩陣的最大子矩陣最大。
資料範圍
n,m<=300。
題解:
①如果沒有p,那麼二維矩陣和就是一維最長連續子串行的dp公升級就可以了:
設f[i][j][k]表示在i行j行之間1~k列這乙個矩形中的最大子矩陣的值
轉移方程:f[i][j][k]=max(f[i][j][k-1]+sum[k],sum[k])
其中sum[k]表示(i,k)-(j,k)這一段一維序列的元素和。
上述在**實現的時候可以壓維,即覆蓋以前的答案。
②根據題意,加一維[1/0]表示到目前為止最優矩陣中有沒有點被更改了:
然後轉移同理,只是如果選擇修改,肯定是修改最小的數,所以使用rmq或者暴力得出即可
#include #include #include #include #include #include #include #include #include #include #include #include #include #define max(a,b) a>b?a:b我只想朝著遠方邊走邊唱,歌唱這生命美麗和迷惘。————汪峰《邊走邊唱》#define min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int dir[4][2]= ,,,};
const double eps = 1e-6;
const double pi = acos(-1.0);
const int inf=0x3f3f3f3f;
const int maxn = 310;
int mat[maxn][maxn];
int minval[maxn];
int sum[maxn];
int dp[maxn][2];
int dp1(int* sum,int m,int p)else}}
return ret;
}int dp2(int* sum,int m,int p)
int ret = -inf;
for(int i = 0; i < m; i++)
return ret;
}int solve(int n,int m,int p)
if(i == 0 && j == n-1)else}}
return ans;
}int main()
}printf("%d\n",solve(n,m,p));
}return 0;
}//czy020202
CZY選講 棋盤迷宮
題目描述 乙個n m的棋盤,表示可以通過,表示不能通過,給出q個詢問,給定起點和終點,判斷兩點是否聯通,如聯通輸出 yes 否則輸出 no 資料範圍 n,m 500,q 10 6。題解 由於存在兩個方向和不可逆性,標記聯通分量的方法不可行 分治演算法。按照行將棋盤一分為二,進行dp處理 用f i j...
CZY選講 吃東西
題目描述 乙個神秘的村莊裡有4家美食店。這四家店分別有a,b,c,d種不同的美食。lyk想在每一家店都吃其中一種美食。每種美食需要吃的時間可能是不一樣的。現在給定第1家店a種不同的美食所需要吃的時間a1,a2,aa。給定第2家店b種不同的美食所需要吃的時間b1,b2,bb。以及c和d。lyk擁有n個...
CZY選講 黑白染色
題目描述 給出平面上n 個點,試將他們黑白染色,要求染色後無法用一條直線把黑白完全分開。隨便輸出一種方案。資料範圍 n 100000 題解 點數很多,但是可以發現至多需要4個點就可以完成。根據上述結論進行分類討論即可 找三個點,若三點共線,則按圖1方法染色。若三點不共線,再找第四個點,若與其中兩點共...