bnu1065(数位dp)

来源:互联网 发布:java重装机兵机甲咆哮 编辑:程序博客网 时间:2024/06/05 07:39
题意:
#include<stdio.h>int main(){   int n,a[10001];   int T;   int i,j,k;   int ans=0;   scanf("%d",&T);   while(T--)   {       scanf("%d",&n);       ans=0;       for(i=0;i<n;++i)           scanf("%d",&a[i]);       for(i=0;i<n;++i)           for(j=0;j<n;++j)               ans+=(a[i]|a[j]);       printf("%d\n",ans);   }return 0;}

将以上代码优化不超时。

题意就是这么简单

题解:
很巧妙的算法,利用数位dp的思想将位数分开计算,词穷无法描素,具体看代码。

#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#include<math.h>using namespace std;typedef long long lld;#define oo 0x3f3f3f3f#define maxn 10005int is_one[maxn][20];//is_one[i][j]第i个数位数为j是1的个数int sum[maxn];//sum[i]位数为i的和int a[maxn];int main(){    int T,n;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        memset(sum,0,sizeof sum);        memset(is_one,0,sizeof is_one);        for(int i=1;i<=n;i++)        {            int t=a[i];            for(int j=0;j<16;j++)            {                int r=t%2;                if(r)                {                    sum[j]++;                    is_one[i][j]=1;                }                t/=2;            }        }        int ans=0;        for(int i=1;i<=n;i++)        {            for(int j=0;j<16;j++)            {                if(is_one[i][j])                    ans+=n*(1<<j);                else                    ans+=sum[j]*(1<<j);            }        }        printf("%d\n",ans);    }return 0;}


0 0
原创粉丝点击