BZOJ 1296 粉刷匠 分組揹包套DP

2022-05-27 00:57:10 字數 1809 閱讀 4583

剛開始往網路流的方向想。建不出圖。。。

因為每次只能對一行進行染色。每一行都是獨立的。

對於每一行,因為格仔只能染一次,所以可以發現這是乙個多階段決策問題,這個決策就是當前格仔染0還是染1.

令dp[i][j][k](k==0||k==1)表示當前行第i個格仔用了j次染色,且這次染色染為k色 的最多有效格仔。

這樣我們用了o(n*m*m)得出了每一行用了v次染色獲得的最多有效格仔val。

顯然的分組揹包。每乙個組最多選一種。再用o(v*n*m)求一遍分組揹包即可。

總複雜度o((v+m)*m*n).

# include # include 

# include

# include

# include

# include

# include

# include

# include

# include

# include

using

namespace

std;

# define lowbit(x) ((x)&(-x))

# define pi

3.1415926535

# define eps 1e-9

# define mod

100000007

# define inf

1000000000

# define mem(a,b) memset(a,b,

sizeof

(a))

# define for(i,a,n)

for(int i=a; i<=n; ++i)

# define fo(i,a,n)

for(int i=a; ii)

# define bug puts("h

");# define lch p

<<1

,l,mid

# define rch p

<<1|1,mid+1

,r# define mp make_pair

# define pb push_back

typedef pair

pii;

typedef vector

vi;# pragma comment(linker,

"/stack:1024000000,1024000000")

typedef

long

long

ll;int

scan()

void out(int

a)

if(a>=10) out(a/10

); putchar(a%10+'0'

);}const

int n=2505;//

code begin...

int val[55][55], dp[55][55][2], ans[2505

];char s[55][55

];int

main ()

for(j,

1,m) val[i][j]=max(dp[m][j][0],dp[m][j][1

]); }

for(i,

1,n) for (int j=t; j>=0; --j) for (int k=min(j,m); k>=1; --k)

ans[j]=max(ans[j],ans[j-k]+val[i][k]);

printf(

"%d\n

",ans[t]);

return0;

}

view code

粉刷匠的難題

粉刷匠遇到了乙個難題 有n根柱子排成一條直線,需要給柱子塗上顏色,現在共有k種顏色,每根柱子塗不同顏色的費用不同。並且要求相鄰柱子顏色不同。你能幫他計算最小的支出費用嗎?費用通過乙個n k 的矩陣給出,比如cost 0 0 表示柱子0塗顏色0的費用,cost 1 2 表示柱子1塗顏色2的費用。測試輸...

粉刷匠 集體照

有m個種類的球,第i個種類有r i 個球,把球排成一行是使得相鄰兩個球種類不同,問方案數。我們可以乙個種類乙個種類的放球。兩個球中間以及最前最後都有 空 定義非法空指該空兩端是同色球,合法空反之。設f i,j 表示當前做到種類i,有j個合法空。此時有個sum表示空的總數。我們可以列舉這r i 個球放...

牛客 粉刷匠(dp)

有些題目可以進行二維dp,當然這題用四維也可以做。我們先做每一行,f,表示第i個用j次,塗前k個的最大值。做完後,可以把它看作分組揹包問題,每個木板都是乙個物品,再跑一邊dp即可 includeusing namespace std const int n 3e5 10 int f 55 2510 ...