時間限制:c/c++ 1秒,其他語言2秒
空間限制:c/c++ 131072k,其他語言262144k
64bit io format: %lld
給乙個陣列 a,長度為 n,若某個子串行中的和為 k 的倍數,那麼這個序列被稱為「k 序列」。現在要你 對陣列 a 求出最長的子串行的長度,滿足這個序列是 k 序列。
第一行為兩個整數 n, k, 以空格分隔,第二行為 n 個整數,表示 a[1] ∼ a[n],1 ≤ n ≤ 105 , 1 ≤ a[i] ≤ 109 , 1 ≤ nk ≤ 107
輸出乙個整數表示最長子序列的長度 m
#include #include using namespace std;
long long sum[100010];
int main()
int imax=0;
int cha;
for(int i = 1; i <= n; i++)
for(int j = n; j > i; j--)
}printf("%d\n",imax);
return 0;
}
字首和求出來倒著算即可。
這樣求出來的一定是最大的,同時減少時間複雜度。
但這其實是子串只是連續的。
不連續的子串行要用dp。
不會啊。
好了,我現在會了。
dp[j]表示到目前為止的數的和模k為j的子串行的最大長度。
然後只要從從第乙個元素掃到最後乙個元素即可。
注意邊界條件:第乙個元素單獨處理,即初始化dp[a[0]%k]=1,其他都置0
狀態轉移方程為dp[(a[i]+j]%k] = max(dp[(a[i]+j]%k],dp[j]+1)
但這裡要注意兩點,
第一,因為每個值在新增乙個新元素時只能更新一次,所以要用乙個flag變數滾動以防陣列被「汙染」
第二,如果dp[(a[i]+j]%k]要被更新為dp[j]+1的條件是dp[j]必須不為0。因為如果為0意味著還沒有數被新增進去,其和模j其實並不成立。
所以dp[j]為0時,dp[(j+a[i])%k]等於原值(上一次計算得到的結果)
本來我是沒想明白為什麼dp[j]為0也需要更新的。
然後我就把dp陣列列印出來看看有什麼區別。
左邊是不更新,右邊是更新;輸入是題目給的樣例,可以自己感受一下。
上海高校金馬五校賽 D 數字遊戲 套路
時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 題目描述 小埃和小森在玩乙個數字遊戲,小埃先從區間 l1,r1 裡選擇1個數字n1,小森看到小埃選的數字後,從 l2,r2 裡選擇1個數字n2,將n1和n2連線在一...
廣東工業大學第十三屆景馳埃森哲杯程式設計競賽
做第一題的時候一點思路都沒有,看到第一眼就覺得應該用遞迴,因為我覺得是一種全排列,但是結果沒做出來,最後隊友用找規律的方法做了出來。而且有乙個點的取值我也不理解,為什麼0級台階時有一種跳法。其實這是個數學問題,類似於c 0,0 1,從0個中取0個,有一種實現的方法,就是乙個也不取。如下 includ...
2017金馬五校賽 K 購買裝備(二分)
題目傳送門 思路 題目要求在最多裝備的基礎上屬性值最小值要最大,典型的求最大化最小值問題。這裡求最多裝備數量是簡單的,接著就是二分答案求最大化最小屬性值。在這mark了一下,可以去看看這篇文章傳送門關於提高cin cout的效率 分別是scanf 加速後的cin 普通cin,效果還是挺明顯的。下面是...