1. 程式人生 > >10.11考試總結

10.11考試總結

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考試總結