【codechef】s=abs(这部分数-剩下的数),求所有选取方式的s之和

65 篇文章 0 订阅
47 篇文章 0 订阅

https://www.codechef.com/KOL15MOS/problems/KOL1502 印度的区域赛,很遗憾赛后不能提交了。。。

原本一直找不到正确的AC打开方式,实在也算道脑洞题吧。下午课上突然想到如何解题了,这种灵光一现的时刻多一点该有多好。。。

一组数据,从中选取一部分数,s=max(这部分数-剩下的数,剩下的数-这部分数),即abs(这部分数-剩下的数)。求所有选取方式的s之和。

一开始一直画画画,想找出什么规律,但是发现345和349这两种情况是的加减是不一样的,所以没有规律可循。然后就懵了两天。

今天课上突然想到,如果给一组数前面加上正负号,那么其中的正数之和如果小于s的一半,最后的结果就是负数。那么这个负数就要被提出来变成正数。如果不处理abs的话,那么所有选取方式的s之和就是0。原本是负的变成正的结果*2。

当然题目给的范围还是很人性化的(1 ≤ Taste scores of ingredients ≤ 10),这使我更坚定了用DP解题的信念。

#include <bits/stdc++.h>
#define ll long long
#define mod 10000000
using namespace std;
int x[1005];
ll dp[1005]; //dp[i]表示当前总和为i时的情况数
int main(){
    int t;
    cin>>t;
    while(t--){
    	memset(dp,0,sizeof(dp)); 
    	int n;
    	cin>>n;
    	ll s=0;
    	for(int i=1;i<=n;++i){
    		cin>>x[i];
    		s+=x[i];
    	}
    	int g=s/2+s%2;
    	dp[0]=1;
    	for(int i=1;i<=n;++i){
    		for(int j=g;j>=0;--j){
    			if(j+x[i]>g)
    				continue;
    			dp[j+x[i]]+=dp[j];
    		}
    	}
    	ll ss=0; 
    	for(int i=0;i<g;++i){
    		ss+=2*dp[i]*(s-i-i);
    	}
    	cout<<ss<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值