jzoj1293,P2933-气象牛(气象测量)【dp】
前言
考試時題目都沒看懂,題目十分玄學
舉個栗子
Sum(sj,s(j+1))Sum(sj,s(j+1))就是Sum(msj,ms(j+1))Sum(msj,ms(j+1))
and
用1~n1~n的數(shù)概況1~10000001~1000000的數(shù)
反正就是十分的玄學
正題
大意
在nn個數(shù)mm里選kk個數(shù)。
如果我們選擇kk個數(shù)那么就有一個序列s=s1,s2...sks=s1,s2...sk表示選擇第sisi個。
然后對于每一個沒有被選擇的數(shù)都會對結果造成一點誤差。
如果沒有被選擇的數(shù)編號為ii,對于每一個ii
如果 i<s1i<s1, 誤差是:2?|Mi?Ms1|2?|Mi?Ms1|
如果sj<i<sj+1sj<i<sj+1,誤差是:|2?Mi?msj?msj+1||2?Mi?msj?msj+1|
如果i>ski>sk,誤差為:2?|Mi?Msk|2?|Mi?Msk|
求選擇最少的數(shù)使誤差小于ee
解題思路
先預處理一個g[i][j]g[i][j]表示在i~ji~j這個區(qū)間內選擇一個數(shù)的最小誤差。
然后用一個f[i][j]f[i][j]表示選擇第ii個數(shù),前面的已經(jīng)取了jj個數(shù)時的情況。
然后每次枚舉一個在ii前面的kk從f[i][j]f[i][j]轉移到f[k][j+1]f[k][j+1],動態(tài)轉移方程
代碼
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; long long n,e,m[105],g[105][105],f[105][105]; int main() {memset(f,127/3,sizeof(f));scanf("%lld%lld",&n,&e);for (ll i=1;i<=n;i++)scanf("%lld",&m[i]);for (ll i=0;i<=n+1;i++)for (ll j=i+1;j<=n+1;j++)for (ll k=i+1;k<=j-1;k++)if (!i) g[i+1][j-1]+=2*abs(m[k]-m[j]);//特判——左else if (j==n+1) g[i+1][j-1]+=2*abs(m[k]-m[i]);//特判——右else g[i+1][j-1]+=abs(2*m[k]-m[i]-m[j]);//預處理f[0][0]=0;for (ll i=0;i<=n;i++)for (ll j=0;j<=n;j++)if (f[i][j]<=e)for (ll k=i+1;k<=n+1;k++)f[k][j+1]=min(f[k][j+1],f[i][j]+g[i+1][k-1]);//動態(tài)轉移for (ll i=2;i<=n+1;i++)if (f[n+1][i]<=e)//枚舉答案{printf("%lld %lld",i-1,f[n+1][i]);return 0;} }總結
以上是生活随笔為你收集整理的jzoj1293,P2933-气象牛(气象测量)【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移速上架 70000 毫安时“能量魔方”
- 下一篇: jzoj1295,P1607-轻轨(庙会