題目給出乙個n*m的矩陣,要求從中找出乙個凸連通塊,使得該連通塊包含k個格仔並且格仔數之和最大,凸連通塊由若干行構成,左右最多各有乙個峰值。
可通過dp解決,每行處理完代表乙個階段,f[i,j,l,r,x,y]表示當前處理第i行,一共選擇了j個格仔,第i行選擇的格仔是[l,r],左右的狀態是x,y表示下降或者上公升。轉移時要列舉每一種狀態,並且列舉上乙個階段的左右位置。找到最大的乙個,在加上第i行的靜態的[l,r]的和。
**:
#include#includeusing
namespace
std;
const
int maxn = 16
;int f[maxn][maxn*maxn][maxn][maxn][2][2
];struct stateg[maxn][maxn*maxn][maxn][maxn][2][2
];int
n,m,k;
intw[maxn][maxn];
intmain();//
記錄上乙個狀態
} }
for(int u=l;u<=r;u++)vf+=w[i][u];
}//左邊收縮,右邊擴張
;//記錄上乙個狀態
} }
for(int u=l;u<=r;u++)vf+=w[i][u];
}//左邊收縮,右邊收縮
;//記錄上乙個狀態
} }
for(int u=l;u<=r;u++)vf+=w[i][u];
}//左邊擴張,右邊收縮
;//記錄上乙個狀態
} }
for(int u=l;u<=r;u++)vf+=w[i][u]; }}
int res=0
; state state;
//查詢最大的終態
for(int i=1;i<=n;i++)
for(int l=1;l<=m;l++)
for(int r=1;r<=m;r++)
for(int x=0;x<=1;x++)
for(int y=0;y<=1;y++)
if(f[i][k][l][r][x][y]>res);
}printf(
"oil : %d\n
",res);
while(state.j)
return0;
}
《演算法競賽高階指南》0x51線性DP 傳紙條
題目要求 給乙個n m的矩陣,求從左上角到右下角的兩條路徑,使得兩條路徑上的值只和最大。從左上角往右下角走的時候只能向下或者向右。在這個問題中階段就是步數,步數與座標點的橫縱座標之和相差乙個常數,所以可以通過座標只和以及兩個點的橫座標來確定當前的狀態集合。此時通過乙個點的所有入邊更新乙個點即可。一共...
《演算法競賽高階指南》0x51線性DP 照相館排列
題目要求將n個人排成不超過五列,每列的人數限制而且遞減,現在要求每行每列都是遞減的方案的數量,通過狀態集合以及轉移規律,f a b c d e 滿足索引遞減的性質 在轉移的時候要維護這個性質,所以除了e以為的所有的索引 1情況都需要考慮,e 1的情況自然維護了這個性質。此外,從高到低排這些人,當前要...
演算法競賽高階指南 0x00
快速冪模板,寫一下快速冪的原理。我們知道,乙個數 n 在二進位制 也可以是其他進製 下可以被表示為 a 1 a 2 2 1 a 3 2 2 a m 2 那麼我們可以考慮將其分拆成二進位制狀態下的每一位,然後做冪運算。這樣做的時間複雜度為 o log 2 n 實現的過程類似於倒過來的分治 當然也可以直...