原题链接:http://codeforces.com/problemset/problem/853/D
大致题意:有n个物品,每个物品的价格是1000或者2000,每次不用积分以全额买下一个物品可以累积10%*商品价格的积分。积分可以在后面的购物中用积分来抵消等同积分的花费。问依次买下这n个物品的最小花费是多少。
先考虑物品价格只有1000的情况,显然每购买10个物品就可以用1000积分来买1个物品,最后剩下不足11物品时,除了最后一个物品用积分抵扣花销,其他的都是全额购买的方案是最优的。因为这种方案用掉了最多的积分。
再考虑加入价格为2000的物品的情况。对于所有的物品,每总价格为2200的分为一组,显然在每一组中都可以用除最后一个物品的其他物品来累计积分从而以0花费得到最后一个价格2000的物品或是最后2个价格为1000的物品。然后除了最后一组物品的总价格不满2200,其他组都可以贡献2000积分用来抵消价格。
对于最后一组,则除了一个价格为2000的物品使用积分其他的全额购买,则可以贡献总价格S * 10 div 11 的积分使用量。
但是要特判当所有物品总价格不超过11000时,最后一个物品价格为2000的情况。
还有就是当所有物品价格为2000时,最后一组的总价格S * 10 div 11的积分为(2*k+1)*100时应该改为2*k*100积分。
代码:
#include <bits/stdc++.h>
using namespace std;
inline void read(int &x){
char ch;
bool flag=false;
for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;
for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
x=flag?-x:x;
}
inline void read(long long &x){
char ch;
bool flag=false;
for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;
for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
x=flag?-x:x;
}
inline void write(int x){
static const int maxlen=100;
static char s[maxlen];
if (x<0) { putchar('-'); x=-x;}
if(!x){ putchar('0'); return; }
int len=0; for(;x;x/=10) s[len++]=x % 10+'0';
for(int i=len-1;i>=0;--i) putchar(s[i]);
}
const int MAXN = 410000;
int a[ MAXN ];
int n;
int main(){
read(n);
int sum=0;
int ans=0;
int tot=0;
for (int i=1;i<=n;i++)
{
read(a[i]);
sum+=a[i]/1000;
if ( a[i]==1000)
tot++;
}
int tmp = 10*sum/11;
if ( sum <= 11 )
tmp = sum - a[n] /1000;
if ( ( !tot ) && ( tmp % 2 ==1 ) )
tmp--;
printf("%d\n",sum*1000-tmp*100);
return 0;
}