UVA - 11039 Building designing

来源:互联网 发布:淘宝主图背景图模板 编辑:程序博客网 时间:2024/05/17 03:14

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> 题目链接:</span><a target=_blank href="http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34028" style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">UVA - 11039 Building designing</a>


       表示这道题目真的是一段血泪史,如此简单我竟然提交了6次,一开始想复杂了,先将所有数字按照绝对值从小到大排序,然后,然后作死的我居然想到了拓扑排序,在按照绝对值排序后,我们可以这样想,从每个Node[i]向所有满足Node[i]*Node[j]<0(j>i)引一条线,这样一来,题目就变成了一个有向无环图求最长路的问题,然后天杀的我写了一个记忆化搜索,勇敢地提交了,结果错了,但并不是因为我的算法问题,然后我就改,我发现什么记忆化搜索都在扯淡,其实每个Node[i]的后续节点一定是在i之后的第一个符号不同的Node[j],所以并不需要什么记忆化搜索,对于每个节点直接找后续节点就好了,但后来一直错。然后在中午去吃饭的路上,我突然想到了应该是数据溢出了,我用Node[i]*Node[j]<0来判断是否异号。

      改了之后就通过了,然后我改了一下之前那个所谓的记忆化搜索,也过了,不过时间上差好多,全都传上来做个纪念吧。

# include <cstdlib># include <cstdio># include <algorithm># include <cmath># include <cstring>using namespace std;  const int size =  500000 + 10;int num[size];bool cmp(int a,int b){return abs(a) < abs(b);}int main(){int i,j,k;    int P;scanf("%d",&P);while (P--){int n;scanf("%d",&n);for (i=0;i<n;i++)scanf("%d",num+i);sort(num,num+n,cmp);for (i=0;i<n;i++) num[i] = num[i] > 0 ? 1 : -1;/*这部分内容很重要,不这样做后面的乘法会溢出*/int ans = 1;for (j=i=0;i<n;i++)if (num[j]*num[i]<0){j = i;ans++;}printf("%d\n",ans);}    return 0;}

# include <cstdlib># include <cstdio># include <algorithm># include <cmath># include <cstring>using namespace std;  const int size =  500000 + 10;int num[size],dp[size];int n;bool cmp(int a,int b){return abs(a) > abs(b);}int getlenth(int x){if (dp[x]!=-1)return dp[x];dp[x] = 1;for (int i=x+1;i<n;i++)if (num[x]*num[i]<0){dp[x] = max(dp[x],getlenth(i)+1);break;}return dp[x];}int main(){int i,j,k;    int P;scanf("%d",&P);while (P--){memset(dp,-1,sizeof(dp));scanf("%d",&n);for (i=0;i<n;i++)scanf("%d",num+i);sort(num,num+n,cmp);for(i=0;i<n;i++)num[i] = num[i]>0?1:-1;int ans = 0;for (i=0;i<n;i++)ans = max(ans,getlenth(i));printf("%d\n",ans);}    return 0;}




0 0