【UOJ 149】机房人民大团结
【题目描述】:
最近,机房出了一个不团结分子:Dr.Weissman。他经常欺骗同学们吃一种“教授糖豆”,使同学们神志不清,殴打他人,砸烂计算机,破坏机房团结。幸运地,一个和谐家认清了Dr.Weissman的本质。机房人民团结在一起,共同对抗Dr.Weissman及“教授糖豆”。
同学们十分具有社会责任感:他们害怕“教授糖豆”流向社会,导致动乱。于是,刚才提到的和谐家身先士卒,为了实验,品尝“教授糖豆”。
每个“教授糖豆”的性质都有所不同。同志们已经研究出每个糖豆对人的影响。具体地,每个糖豆都有一个破坏值,吃掉这颗糖豆后,身先士卒的和谐家会对机房造成一定的破坏,破坏程度为先前累积的破坏值加上本次食用糖豆的破坏值,而且这颗“教授糖豆”的破坏值会加入累积。为了减小实验造成的破坏,同学们准备了几颗“治疗糖豆”,功能是无条件将累积的“破坏值”清零。(注意:吃了“教授糖豆”后会立即开始破坏,破坏结束后才有可能吃“治疗糖豆”)
由于实验要求,和谐家只能按照给定的顺序吃掉“教授糖豆”,但可以随时吃掉一颗或多颗“治疗糖豆”。
你能帮助和谐家同志尽量减小实验所造成的破坏吗?
【输入描述】:
第一行,两个数,用空格,分隔开,一个n,一个m。(n,m均为正整数。)n表示“教授糖豆”的数目,m表示“治疗糖豆”的数目。
剩余n行,每行1个正整数,表示“教授糖豆”的破坏值。和谐家必须按照给定的顺序,一次一个,吃掉所有“教授糖豆”。
【输出描述】:
一行,一个数,表示实验造成的最小破坏。
【样例输入】:
3 1
1 2 3
【样例输出】:
7
【样例说明】:
1+(1+2)+(此时吃了“治疗糖豆”累积值清零)+3 = 7
【时间限制、数据范围及描述】:
时间:1s 空间:256M
对于100%的数据,1<=n<=100,m<=n
所有破坏值的加和小于10^9。
题解:奇怪的DP增加了
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<bits/stdc++.h> typedef long long ll; using namespace std; const int N=102; const int oo=0x3f3f3f3f; int n,m; ll ans=(1LL<<60); int a[N],sum[N],vis[N]; void wow(){ int tot=0; ll sum=0; for(int i=1;i<=n;i++){ sum+=(ll)(a[i]+tot); if(vis[i]==1) tot=0; else tot+=a[i]; } ans=min(ans,sum); } void work1(){ int xx=pow(2,n+1); for(int i=1;i<xx;i++){ //cout<<i<<endl; int x=i; int nu=0; for(int j=1;j<=n;j++) if((1<<(j-1)&x)!=0) { vis[j]=1; nu++; } else vis[j]=0; if(nu==m) wow(); } printf("%d\n",ans); } ll f[105][105][105]; void work2(){ //cout<<42; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) for(int k=0;k<=n;k++) f[i][j][k]=(1LL<<60); f[0][0][0]=0; for(int i=1;i<=n;i++){ for(int j=0;j<i;j++) for(int k=0;k<i;k++) f[i][j][k]=f[i-1][j][k]+ll(sum[i]-sum[k-1]); for(int j=1;j<=i;j++) for(int k=0;k<i;k++) f[i][j][i]=min(f[i][j][i],f[i-1][j-1][k]+a[i]); } for(int i=0;i<=m;i++) for(int j=0;j<=n;j++) ans=min(ans,(ll)f[n][i][j]); printf("%lld\n",ans); } int main(){ scanf("%d %d",&n,&m); //cout<<n; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } //if(n<=20) work1(); //else work2(); //else cout<<"66666666"; return 0; }