CodeForces 703B(容斥定理)

题目链接: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\n",ans);
45     }
46     return 0;
47 }

 

posted @ 2016-08-22 18:04  马丁黄瓜啊  阅读(304)  评论(0编辑  收藏  举报