ZOJ 3685 ZJU2013年01月月赛J题 Cube

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3685

这道题刚开始想了其他很多思路,包括DP什么都没有头绪。当时还有40多分钟,就想要专心过这题了。

然后就写了复杂度为O(2^n)的程序,算出了前25个之后,发现从第15个开始,答案不是0就是1。

分析一下可以发现,改变正负号不改变结果奇偶性,当1 ~ n中奇数为奇数个时,答案就为奇数,不然就是偶数。

可以计算得到1^3 + 2^3 + ... + n^3 = n^2 * (n+1)^2 / 4

如果n>=15时,假如答案不是0就是1这点成立,等价于从1^3 , 2^3 , 3^3 , ... , n^3中选取一些数字,使得和为 n^2 * (n+1)^2 / 8(取整)有解。

 

整数拆分问题!!当然不能用dp的方法做,抱着试试的心理写了裸的dfs,然后就过了。这应该是说明解的数量非常多吧。

n<15的所有情况,都可以暴力枚举算出来,我直接打表写在程序里了。

当然,我现在无法证明,为什么大于14的时候一定会有解,找到的话,会添加到这里。 

代码如下:

 

 1 #include<cstdio>

 2 #include<cstring>

 3 using namespace std;

 4 typedef long long ll;

 5 const char ans[20][20]={

 6 "",

 7 "+",

 8 "-+",

 9 "-++",

10 "-+++",

11 "-++++",

12 "-+++-+",

13 "+---+++",

14 "+--+--++",

15 "+--+-+--+",

16 "-+-+++++++",

17 "-++-+--++++",

18 "+--++---+-++",

19 "--+++++-+++++",

20 "-++-+--++--+-+"

21 };

22 char s[10010];

23 ll s3[10010];//预处理三次方

24 bool dfs(ll sum,int n){

25     for(int i=n;i>0;i--)if(sum>=s3[i]){

26         if(sum - s3[i]==0 || dfs(sum - s3[i],i-1)){

27             s[i-1]='+';

28             return true;

29         }

30     }

31     return false;

32 }

33 void solve(ll n){

34     for(int i=0;i<n;i++)s[i]='-';

35     ll sum=n*n*(n+1)*(n+1)/8;

36     dfs(sum,n);

37     for(int i=n-1;i>=0;i--)putchar(s[i]);

38     puts("");

39 }

40 int main()

41 {

42     for(ll i=1;i<=10000;i++) s3[i]=i*i*i;

43     int n;

44     while(~scanf("%d",&n)){

45         if(n<15)puts(ans[n]);

46         else solve(n);

47     }

48     return 0;

49 }

 

做这场月赛的时候在最后两分钟,调出来过了,绝杀。。爽

你可能感兴趣的:(cube)