greedy tino(教训!)

贪婪的tino
#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;
#define INF 0x7fffffff
#define OFFSET 2000

int dp[101][4001];
int list[101];

int max(int a,int b,int c)
{
	a=(a>b)?a:b;
	
	return a>c?a:c;
}

int main()
{
	int T;
	int cas=0;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		int cnt=1;
		
		bool haszero=false;
		//是list的问题!!! 
		//记住这次的教训!以后使用ind或者cnt作为下标的累加的时候
		//先置为0,然后在循环的开头!使用cnt++
		//否则如果置为1,在循环的结尾使用cnt++,一定要在循环之后写上cnt--
		//否则最后cnt会多一个!  
		for(int i=1;i<=n;i++)
		{
            
			scanf("%d",&list[cnt]);
			if(list[cnt]==0)
			{
				cnt--;
				haszero=true;
			}cnt++; 
		}
		cnt--; 
        //for(int i=1;i<=cnt;i++)cout<<list[i]<<endl;
        n = cnt;
        cout<<n<<endl;
		// for (int i = 1; i <= n; i ++) { //输入n个柑橘重量
			// scanf ("%d",&list[++ cnt]);
			// if (list[cnt] == 0) { //若当前输入柑橘重量为0
				// cnt --; //去除这个柑橘
				// haszero = true; //并记录存在重量为0的柑橘
			// }
		// }
		// n = cnt;
		
		for(int i=-2000;i<=2000;i++)
		{
			dp[0][i+OFFSET]=-INF;
		}
		//假如说写到上面去if(i==0)每次都得判断一下,不应该 
		dp[0][0+OFFSET]=0;
		//这个cnt在这个时候有用! 
		for(int i=1;i<=cnt;i++)
		{
			for(int j=-2000;j<=2000;j++)
			{
				int tmp1,tmp2,tmp3;
				//这里忘记初始化参数 
				tmp1=dp[i-1][j+OFFSET];
				tmp2=tmp3=-INF;
				 
				//在上一个的基础上在左边加,应该防止他们之间的差距大于 
				if(j+list[i]<=2000 && dp[i-1][j+OFFSET+list[i]]+list[i]!=-INF)
				{
					tmp2=dp[i-1][j+OFFSET+list[i]]+list[i];
				 } 				
				 if(j-list[i]>=-2000 && dp[i-1][j+OFFSET-list[i]]+list[i]!=-INF)
				{
					tmp3=dp[i-1][j+OFFSET-list[i]]+list[i];
				 } 
				 int up=max(tmp1,tmp2,tmp3);
				 dp[i][j+OFFSET]=up; 
			}
		}
		cas++;
		//错!!!
		//有presentation error,改到的时候,少了空格的就改了一个,没有改另一个
		if(dp[n][0+OFFSET]==0)
		{
			if(haszero==true)
			{
				printf("Case %d: ",cas);
				printf("0\n");
		 	}
			 else
			 {
			 	printf("Case %d: ",cas);
			 	printf("-1\n");
				 }	
		}
		else
		{
			printf("Case %d: ",cas);
			printf("%d\n",dp[n][0+OFFSET]/2);
		}
		// printf("Case %d: ",++ cas);//按题目输出要求输出
		// if (dp[n][0 + OFFSET] == 0) { //dp[n][0]为0
			// puts( haszero == true ? "0" : "-1");//根据是否存在重量为0的柑橘输出0或-1
		// } else printf("%d\n",dp[n][0 + OFFSET] / 2); //否则输出dp[n][0] / 2
	} 
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值