题目链接:http://codeforces.com/contest/703/problem/B
解题思路:
第一次写 先求出每个点到其他点的价值,并将其记录 dp[i][j]=1(i<j),然后算出周围一圈的价值,当然有dp[i][j]来防止重复计算,超时
第二次写 将二维数组用一维数组代替 方法是 dp[i][j]=dp[i*10+j] (i<j); 然后求出一圈的价值,dp[i] 来防止重复计算,超时
第三次写 先求出所有点价值的和sum,以及一圈的价值ans,如果 省会 k==1 则在总和中减去前一个和后一个,即减去第2个和第n个
ans+=(tem-a[1])*a[1];
sum-=a[1];
dp[x]=1;//防止重复计算
关键点是找到前一个和后一个,然后计算到ans中,同时sum-=当前值,记得dp[x]=1;
第一个和最后一个特殊处理。
Ac code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxx 200002 4 int dp[maxx]; 5 long long nar[maxx]; 6 int main() 7 { 8 int n,k,ka,i; 9 while(scanf("%d%d",&n,&k)!=EOF) 10 { 11 long long sum=0; 12 memset(dp,0,sizeof(dp)); 13 for(i=1; i<=n; i++) 14 { 15 scanf("%I64d",&nar[i]); 16 sum+=nar[i]; 17 } 18 long long ans=nar[1]*nar[n]; 19 for(int i=1; i<n; i++) 20 ans+=nar[i]*nar[i+1]; 21 for(i=1; i<=k; i++) 22 { 23 scanf("%d",&ka); 24 long long tem=sum; 25 if(ka==1) 26 { 27 if(!dp[2])tem-=nar[2]; 28 if(!dp[n])tem-=nar[n]; 29 } 30 else if(ka==n) 31 { 32 if(!dp[1])tem-=nar[1]; 33 if(!dp[n-1])tem-=nar[n-1]; 34 } 35 else 36 { 37 if(!dp[ka-1])tem-=nar[ka-1]; 38 if(!dp[ka+1])tem-=nar[ka+1]; 39 } 40 ans+=(tem-nar[ka])*nar[ka]; 41 sum-=nar[ka]; 42 dp[ka]=1; 43 } 44 printf("%I64d ",ans); 45 } 46 return 0; 47 }