思路:一開始看到這題的時候想dp,可是發現貌似不行。。因為有字首也有字尾,而且有的字尾會覆蓋到現在的字首,這就不滿足無後效性了啊!
但是有個很巧妙的思路:如果我們知道a[i]的最大值,那麼p的數量和q的數量也確定了。所以序列長度也確定了,設m為序列長度。
而且對於每個a[i]都代表了乙個固定數量的p和q和長度。
因此,長度大於m/2的字首,我們可以用總的p和總的q減去它,轉換成小於等於m/2長度的字首字尾。
這樣我們可以設計dp為f[i][j][k],代表從左往右i個中有j個p,從右往左i個有k個p,這樣f[(m+1)/2]的位置就是最終答案!
注意要記錄乙個pre陣列記錄這個狀態的最優解是從哪個位置轉移過來的。
1 #include2 #include3 #include4 #include5 #include6#define ll long long
7 ll a[200005];8
const ll pw=9705276;9
const ll qw=12805858;10
int c[200005][2],n,pre[205][205][205][2],w[205][205],f[205][205][205
];11
int ans[200005
],cn;
12int
read()
15while ('0'
<=ch&&ch<='9')
16return t*f;17}
18void
init()24}
25void
solve()
30int totp=-1,totq=-1;31
for (int i=0;(ll)i*pw<=a[mxpos];i++)
32if ((a[mxpos]-(ll)i*pw)%qw==0)37
for (int i=0;i)
45if (p!=-1&&p+q<=totp+totq)50}
51int m=totp+totq;
52for (int i=0;i)else58}
59 f[0][0][0]=0;60
for (int i=1;i<=m/2;i++)
61for (int j=0;j<=i;j++)
62for (int k=0;k<=i;k++)71}
72}73 f[i][j][k]=s+w[i][j]+((k==j)?0
:w[i][k]);74}
75int ansi=-1,ansj=-1,ansk=-1;76
for (int k=0;k<=m%2;k++)
77for (int i=0;i<=m/2;i++)84}
85if (m%2) ans[m/2]=ansk;
86for (int i=m/2;i>0;i--)
94for (int i=0;i)
95if (ans[i]) printf("q"
);96
else printf("p"
);97}98
intmain()
XJOI網上同步訓練DAY3 T1
思路 看來我真是思博了,這麼簡單的題目居然沒想到,而且我對複雜度的判定也有點問題。首先我們選了乙個位置i的b,那一定只對i和以後的位置造成改變,因此我們可以這樣看 我們從前往後選,發現乙個位置的s和r相等,然後我們就選這個位置的bi,由於bi會改變當前位置,因此當前位置的vi我們就能吃到了。所以,每...
XJOI網上同步測試DAY14 T2
思路 先考慮在d高度的最小圓覆蓋,再一層一層往下走時,可以保證圓心與最開始的圓相同的時候答案是最優的。時間複雜度o n 有乙個坑點,就是我用了srand time null 就t了,rp太差了。include include include include include include const...
資訊傳遞(NOIP2015提高組Day1T2)
題目描述 有n個同學 編號為1到n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取資...