生活随笔
收集整理的這篇文章主要介紹了
[LOJ500]ZQC的拼图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:
給你一個m*m的格子,讓你往里面放給定的直角三角形,直角頂點必須放在右上角且不能翻轉,但是可以把所有給定的三角形放大一個整數倍k,問至少放大幾倍能使格子的左下角和右上角連起來?(可以超出邊界)
思路:
二分答案+DP。
二分一個解m,然后用DP來檢驗。
用f[i][j]表示放到第i個三角形,橫坐標到達j時縱坐標的最大值。
轉移方程為f[i][j]=max{f[i-1][k]+(m-(j-k)*x[i])/y[i]}。
最后判斷一下f[n][m]>=m即可。
1 #include<cstdio>
2 #include<cctype>
3 #include<algorithm>
4 inline
int getint() {
5 register
char ch;
6 while(!isdigit(ch=
getchar()));
7 register
int x=ch^
'0';
8 while(isdigit(ch=getchar())) x=(((x<<
2)+x)<<
1)+(ch^
'0');
9 return x;
10 }
11 const int _inf=-
0x80000000;
12 const int N=
100,M=
101;
13 std::pair<
int,
int>
t[N];
14 int n,m;
15 int f[
2][M];
16 inline
bool check(
const int &
k) {
17 f[
0][
0]=
0;std::fill(&f[
0][
1],&f[
0][m+
1],_inf);
18 f[
1][
0]=
0;std::fill(&f[
1][
1],&f[
1][m+
1],_inf);
19 for(register
int i=
0;i<n;i++
) {
20 for(register
int j=
0;j<=m&&j<=k/t[i].first;j++
) {
21 const int tmp=(k-j*t[i].first)/
t[i].second;
22 for(register
int l=m-j;l>=
0;l--
) {
23 f[i&
1][j+l]=std::max(f[i&
1][j+l],f[!(i&
1)][l]+
tmp);
24 }
25 }
26 }
27 return f[!(n&
1)][m]>=
m;
28 }
29 int main() {
30 n=getint(),m=
getint();
31 for(register
int i=
0;i<n;i++
) {
32 t[i]=
std::make_pair(getint(),getint());
33 }
34 int l=
0,r=
1e8;
35 while(l<
r) {
36 const int mid=(l+r)>>
1;
37 if(check(mid)) {
38 r=
mid;
39 }
else {
40 l=mid+
1;
41 }
42 }
43 printf(
"%d\n",(l+r)>>
1);
44 return 0;
45 }
?
轉載于:https://www.cnblogs.com/skylee03/p/7777343.html
總結
以上是生活随笔為你收集整理的[LOJ500]ZQC的拼图的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。