浙大acm2059,我用贪心算法但是老wa,哪为高手能帮我解决

HelpMeACM 2004-08-09 04:46:59
//http://acm.zju.edu.cn/show_problem.php?pid=2059
#include<stdio.h>
#include<math.h>
#define N 200

int main()
{
int i,j,k,t,w[N];
char n;
//如果使用unsigned int类型,就WA
while(scanf("%d",&n),n!=-1)
{
int s1=0,s2=0;

for(i=0,k=(n>>1);i<k;i++)
{scanf("%d",&w[i]);s1+=w[i];}

for(;i<n;i++)
{scanf("%d",&w[i]);s2+=w[i];}

if(((s1+s2)&1)) {printf("Sorry\n");continue;}

bool s;
while(1)
{
s=true;
for(i=0;i<k;i++)
for(j=k;j<n;j++)
{
if(fabs((s1-w[i]+w[j])-(s2+w[i]-w[j]))<fabs(s1-s2))
{
s=false;
s1=s1-w[i]+w[j];
s2=s2+w[i]-w[j];
t=w[i];w[i]=w[j];w[j]=t;
}//if
}

if(s)
{
//if(s1>s2)
//{t=s1;s1=s2;s2=t;}
//printf("%d %d\n",s1,s2);
if(s1==s2) printf("%d\n",s1);
else printf("Sorry\n");
break;
}
}//while
}//while
return 1;
}
...全文
269 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
HelpMeACM 2004-08-12
  • 打赏
  • 举报
回复
看了xiaojun_wu(琅琅) 的提示明白。
还有你的答案能不能给我看
xiaojun_wu 2004-08-12
  • 打赏
  • 举报
回复
#include<stdio.h> //AC table[i]表示两边差i时短边最大高度
#include<string.h>

#define MAX 2000

int table[MAX];
int attach[MAX];
int sum;
void Add( int height)
{
int loop;
int last;
int temp;
memcpy(attach,table,MAX*4);
for(loop=0; loop <= sum ; loop++)
if( table[loop] != -1 ){
last=table[loop];
temp= table[height+loop] > last ? table[height+loop]:last;
attach[height+loop] = attach[height+loop] > temp ? attach[height+loop]:temp;

if(height >= loop){
temp = table[height-loop] > last+loop ? table[height-loop]:last+loop;
attach[height-loop] = attach[height-loop] >temp ?table[height-loop] :temp;
}
else{
temp = table[loop-height] > last+height ? table[loop-height]:last+height;
attach[loop-height] = attach[loop-height] > temp ? attach[loop-height] :temp;
}
}
memcpy( table, attach , MAX*4);
}
void init()
{
table[0]=0;
sum=0;
for(int loop=1;loop<MAX;loop++)
table[loop]=-1;
}

void PR()
{
for(int loop=0;loop<=11;loop++)
printf("%d ",table[loop]);
printf("\n");
}
int main()
{
int num;
int loop;
int temp;

while(scanf("%d",&num)!=EOF && num >=0 )
{
init();
for(loop = 0;loop < num;loop++){
scanf("%d",&temp);
Add(temp);
sum+=temp;
//PR();
}

if(table[0] == 0)
printf("Sorry\n");
else
printf("%d\n",table[0]);
}
return 0;
}
xiaojun_wu 2004-08-11
  • 打赏
  • 举报
回复
HelpMeACM,感觉你对DP的理解不对吧,1711是DP出来的??不明白。1711明显是一个计数的DFS啊,哪位大哥DP出来能不能给小弟看看?还有,这道题从两位同学的代码来看,该是对题意的理解有误:
关键:并不是所有的水晶都要用!所以,这就注定搜索是失败的!
该题的我所知道的方法还只有DP(动态规划),哪位大哥有更好的方法,还望给小弟说一声。谢过了。
楼主可以到zju的论坛搜索一下相关的讨论,应该会有所启发
xiaojun_wu 2004-08-10
  • 打赏
  • 举报
回复
不是DP不可以,而是你的DP不可以!
ZhangJingZJU 2004-08-10
  • 打赏
  • 举报
回复
为什么dp不可以
HelpMeACM 2004-08-10
  • 打赏
  • 举报
回复
我用DP,也WA
#include <iostream.h>

#define MAXSIZE 300
int numberOfSolutions, listlength, list[MAXSIZE];
int used[MAXSIZE]; // used[i] is 1 if list[i] is used in the sum

int DivSum;

void findSum (int sum, int iEnd, int numSkipped)
{
if (iEnd == listlength) return;
int newsum = sum - list[iEnd];
if ((numSkipped != list[iEnd])&&(newsum >= 0))
{
used[iEnd] = 1;
if (newsum == 0)
{
numberOfSolutions++;
//for (int i = 0; i<iEnd; i++)
//if (used[i]) cout << list[i] << '+';
//cout << list[iEnd] << endl;
cout<<DivSum<<endl;
}
else
findSum(newsum, iEnd+1, -1);
}

used[iEnd] = 0;
findSum(sum, iEnd+1, list[iEnd]);
}

int main()
{
int sum,i;
while (cin >> listlength,listlength!=-1)
{
for (i=0,sum=0; i < listlength; i++)
{cin >> list[i];sum+=list[i];}

if(sum&1) {cout << "Sorry" << endl;continue;}

numberOfSolutions = 0;
sum=(sum>>1);DivSum=sum;
findSum(sum, 0, -1);
if (numberOfSolutions == 0) cout << "Sorry" << endl;
}
return 0;
}
Leaveye 2004-08-10
  • 打赏
  • 举报
回复
弱弱地问一声,,DP和WA都是什么东东?
HelpMeACM 2004-08-10
  • 打赏
  • 举报
回复
1711是用这个DP解决
为什么用到这题目2059就不行
将1711的sum改成2059总和一半,如果等于就打印.否则Sorry
有什么错误
gnefuil 2004-08-10
  • 打赏
  • 举报
回复
贪是贪不出来啦
用dp

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧