HU-586 Sum(DP)
http://acm.hdu.edu.cn/showproblem.php?pid=5586
Sum
Time Limit:2000/1000 MS(Java/Others) メモリLimit:65536/65536 K(Java/Others)
Problem Description
The re is a number sequence
A 1,A 2….An,you can select a interval[l,r]or not,all the numbers
Ai(l≦i≦r) will become
f(Ai)
f(x)=(1890 x+143)mod 1007.After that,the sum of n numbers shound be as much possible.What is the maximm sum?
Input
The re are multiple test cases.
First line of each case contains a single integer n.
(1≦n≦105)
Next LINE contains n integers
A 1,A 2….An.
(0≦Ai≦104)
It's garanted that
Σn≦106.
Output
For each test case,output the answer in a line.
Sample Input
Sample Output
公式DPの方法とは違って、自分のDPの方が早いような気がします。
公式方法:令a[i]=f(a[i])-a[i]を求め、最大連続サブシーケンスと最大増加できる値を知ることができる。
個人の考え方:
DPはまだよくないです。考える時間は長いです。
いろいろ考えた末、dp[i][j](j=0,1,2)で現在の状態を表すことができると思いました。
dp[i][0]は現在置換区間に入っていないことを示しています。dp[i-1][0]から移動するしかないです。
dp[i][1]は現在置換区間にあり、dp[i-1][0]とdp[i-1][1]から移行することができます。
dp[i][2]は現在置換区間から離れていることを示し、dp[i-1][1]とdp[i-1][2]によって移動することができます。
状態移行方程式は以下の通りです。
dp[i][0]=dp[i-1][0]+a[i]
dp[i][1]=max(dp[i-1][0],dp[i-1]、[1])+f(a[i]);
dp[i]、[2]=max(dp[i-1][1],dp[i-1]、[2])+a[i]
Sum
Time Limit:2000/1000 MS(Java/Others) メモリLimit:65536/65536 K(Java/Others)
Problem Description
The re is a number sequence
A 1,A 2….An,you can select a interval[l,r]or not,all the numbers
Ai(l≦i≦r) will become
f(Ai)
f(x)=(1890 x+143)mod 1007.After that,the sum of n numbers shound be as much possible.What is the maximm sum?
Input
The re are multiple test cases.
First line of each case contains a single integer n.
(1≦n≦105)
Next LINE contains n integers
A 1,A 2….An.
(0≦Ai≦104)
It's garanted that
Σn≦106.
Output
For each test case,output the answer in a line.
Sample Input
2
10000 9999
5
1 9999 1 9999 1
Sample Output
19999
22033
タイトル:n個の数A 1,A 2…A nをあげて、区間を選択してもいいです。区間の中で、各数xはf(x)になります。その中でf(x)=(1890*x+143)mod 10007。最後のn個の数と最大可能性はどれぐらいですか?公式DPの方法とは違って、自分のDPの方が早いような気がします。
公式方法:令a[i]=f(a[i])-a[i]を求め、最大連続サブシーケンスと最大増加できる値を知ることができる。
個人の考え方:
DPはまだよくないです。考える時間は長いです。
いろいろ考えた末、dp[i][j](j=0,1,2)で現在の状態を表すことができると思いました。
dp[i][0]は現在置換区間に入っていないことを示しています。dp[i-1][0]から移動するしかないです。
dp[i][1]は現在置換区間にあり、dp[i-1][0]とdp[i-1][1]から移行することができます。
dp[i][2]は現在置換区間から離れていることを示し、dp[i-1][1]とdp[i-1][2]によって移動することができます。
状態移行方程式は以下の通りです。
dp[i][0]=dp[i-1][0]+a[i]
dp[i][1]=max(dp[i-1][0],dp[i-1]、[1])+f(a[i]);
dp[i]、[2]=max(dp[i-1][1],dp[i-1]、[2])+a[i]
#include <cstdio>
#include <algorithm>
using namespace std;
int n,num,i,dp[2][3];//dp[i&1][0] ,dp[i&1][0] ,dp[i&1][2]
inline int f() {
return (1890*num+143)%10007;
}
int main() {
while(1==scanf("%d",&n)) {
dp[0][0]=dp[0][1]=dp[0][2]=0;
for(i=1;i<=n;++i) {
scanf("%d",&num);
dp[i&1][0]=dp[(i-1)&1][0]+num;
dp[i&1][1]=max(dp[(i-1)&1][0],dp[(i-1)&1][1])+f();
dp[i&1][2]=max(dp[(i-1)&1][1],dp[(i-1)&1][2])+num;
}
printf("%d
",max(dp[n&1][0],max(dp[n&1][1],dp[n&1][2])));
}
return 0;
}