剛開始往網路流的方向想。建不出圖。。。
因為每次只能對一行進行染色。每一行都是獨立的。
對於每一行,因為格仔只能染一次,所以可以發現這是乙個多階段決策問題,這個決策就是當前格仔染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 # includeview code# 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;
}
粉刷匠的難題
粉刷匠遇到了乙個難題 有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 ...