贪婪的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;
}