10.11考試總結
阿新 • • 發佈:2018-10-13
sum 就是 printf 暴力 考試 %d 0.11 負數 int
10.11考試總結
全是DP實際上發現暴力也能有部分分.......
三角形牧場
DP......當時總是感覺不像啊
需要處理的就是枚舉三角形邊長可能出現的情況。因為周長在輸入端時候就可以確定了,所以只需要通過枚舉兩條邊就可以強行算出第三條邊.....
所以就省空間+時間....
f[0][0] = 1; for (int i=1; i<=n; ++i) for(int j=half; j>=0; j--) for(int k=j; k>=0; k--) if(j >= d[i] && f[j-d[i]][k] || k >= d[i] && f[j][k-d[i]]) f[j][k] = 1;
查找邊數的存在情況
然後就是判斷是否能組成三角形與否
for (int i=half; i>=1; --i)
for (int j=i; j>=1; --j)
if (f[i][j])
f (check(i, j, tot - i - j))
ans = max(ans, area(i, j, tot - i - j));
然後就做完了.......
多米諾骨牌
又是DP.......我莫得感情直接算出上下的差,然後直接計算一邊。不過這個有負數的答案出現,所以要處理一下變成正數就好了...
然後再找答案就好了
for(int i=1; i<=n; i++)
for(int j=-5000; j<=5000; j++)
f[i][j+M] = min(f[i-1][j-c[i]+M], f[i-1][j+c[i]+M]+1);
for(int i=0; i<=5000; i++)
{
ans = min(f[n][i+M], f[n][-i+M]);
if(ans <= 1000)//因為n小於1000,所以最多翻轉肯定是1000以內
{
printf("%d\n", ans);
break;
}
}
修剪草坪
把自己列出的公式推導一下。
首先f[i]是作為一個結束點,f[j]是斷點。
所以
f[i]=max(f[i],f[j-1]+a[j+1]+a[j+2]……a[i])(i-k<=j<=i)
然後發現可以上一波前綴和優化。
f[i]=max(f[i],f[j-1]+sum[i]-sum[j]) (i-k<=j<=i)
然後發現在i中,sum[i]其實是一個定值,所以可以提出來
f[i]=max(f[i],f[j-1]-sum[j])+sum[i] (i-k<=j<=i)
發現只與j有關聯,並且始終找最大值。
然後滾去了解了一下什麽是單調隊列,保證隊列內數字單調,輸出前面的最大值就可以了
IL ll top(int i)
{
d[i] = f[i-1] - sum[i];
while (head <= tail && d[q[tail]] < d[i]) tail--;
q[++tail] = i;
while (head <= tail && q[head] < i - k) head++;
return d[q[head]];
}
單調隊列,然後用這個來找最大值
for(int i=1; i<=n; i++) f[i] = top(i) + sum[i];
一個簡單的任務
這個任務並不簡單
狀壓DP......勸退
10.11考試總結