【CH5105】Cookies
生活随笔
收集整理的這篇文章主要介紹了
【CH5105】Cookies
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
也是一道線型動態(tài)規(guī)劃的好題……
讀入每個人的貪婪度之后,對其按照從大到小的順序排序,定義狀態(tài)f[i][j]為前i個人(排序后)分j個餅干的答案,那么答案為f[n][m],考慮狀態(tài)轉移方程。
1、若給第i個人的餅干數(shù)大于1 ,那么我們將這i個人的餅干數(shù)都減1(總共減n),他們的怨氣值是不會改變的,因而這種情況下,f[i][j]=f[i][j-i].
2、若給第i個人的餅干數(shù)等于1,那么我們枚舉一個k(0≤k<i),表示從k之后一直到i所有的人的餅干數(shù)都是1,那么f[i][j]=f[k][j-(i-k)]+k*∑g[c[p]]? ? (k<p<=i).
我們先預處理出g數(shù)組的前綴和,即可實現(xiàn)O(n)的轉移。
綜上,我們在兩種決策中取最優(yōu)即可。另外,本題要求輸出方案,我們只需在狀態(tài)轉移時記錄每個狀態(tài)的前驅即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int n,m,f[40][5010],a[40][5010],b[40][5010]; 7 int s[50],ans[50]; 8 int g[50],c[50]; 9 bool cmp(int x,int y) { 10 return g[x]>g[y]; 11 } 12 void calc(int x,int y) { 13 if(!x) return ; 14 calc(a[x][y],b[x][y]); 15 if(a[x][y]==x) 16 for(int i=1;i<=x;i++) ans[c[i]]++; 17 else 18 for(int i=a[x][y]+1;i<=x;i++) ans[c[i]]=1; 19 } 20 int main() { 21 scanf("%d%d",&n,&m); 22 for(int i=1;i<=n;i++) { 23 scanf("%d",&g[i]); 24 c[i]=i; 25 } 26 sort(c+1,c+n+1,cmp); 27 memset(f,0x3f,sizeof(f)); 28 f[0][0]=0; 29 for(int i=1;i<=n;i++) s[i]=s[i-1]+g[c[i]]; 30 for(int i=1;i<=n;i++) 31 for(int j=i;j<=m;j++) { 32 f[i][j]=f[i][j-i]; 33 a[i][j]=i; 34 b[i][j]=j-i; 35 for(int k=0;k<i;k++) 36 if(f[i][j]>f[k][j-(i-k)]+k*(s[i]-s[k])) { 37 f[i][j]=f[k][j-(i-k)]+k*(s[i]-s[k]); 38 a[i][j]=k; 39 b[i][j]=j-(i-k); 40 } 41 } 42 printf("%d\n",f[n][m]); 43 calc(n,m); 44 for(int i=1;i<=n;i++) printf("%d ",ans[i]); 45 return 0; 46 } AC Code?
轉載于:https://www.cnblogs.com/shl-blog/p/10660961.html
總結
以上是生活随笔為你收集整理的【CH5105】Cookies的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop集群(一) Zookeepe
- 下一篇: JAVA学习笔记_五JAVA开发中的WE