code vs 1966 乘法遊戲
阿新 • • 發佈:2018-12-23
1966 乘法遊戲
時間限制: 1 s 空間限制: 128000 KB 題目等級 : 黃金 Gold 題目描述 Description乘法遊戲是在一行牌上進行的。每一張牌包括了一個正整數。在每一個移動中,玩家拿出一張牌,得分是用它的數字乘以它左邊和右邊的數,所以不允許拿第1張和最後1張牌。最後一次移動後,這裡只剩下兩張牌。
你的目標是使得分的和最小。
例如,如果數是10 1 50 20 5,依次拿1、20、50,總分是 10*1*50+50*20*5+10*50*5=8000
而拿50、20、1,總分是1*50*20+1*20*5+10*1*5=1150。
輸入檔案的第一行包括牌數(3<=n<=100),第二行包括N個1-100的整數,用空格分開。
輸出描述 Output Description輸出檔案只有一個數字:最小得分
樣例輸入 Sample Input6
10 1 50 50 20 5
3650
此題屬於區間dp,第一眼看感覺跟石子合併有點像,於是就按照那種方式編寫。但是除錯的過程中發現會出現負值,應該是資料超範圍了,所以發現考慮不周。經大神指點發現沒有特殊處理f[i][i+1]的情況,相鄰兩個無法運算所以很顯然應該是0,但是如果不初始化就會是最大值,那麼很顯然會錯。但是貌似還是不對,於是發現題意理解有誤。唉,於是重新寫,就寫成了這個樣子。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int i,j,k,n,m; int num[110],f[110][110]; using namespace std; int main() { scanf("%d",&n); memset(f,127/3,sizeof(f)); for (i=1;i<=n;i++) { scanf("%d",&num[i]); f[i][i]=num[i]; } for (i=1;i<=n-1;i++) f[i][i+1]=0; for (i=2;i<=n;i++) { for (j=1;j<=n-i+1;j++) { for (k=j+1;k<=i+j-2;k++) f[j][i+j-1]=min(f[j][i+j-1],f[j][k]+f[k][i+j-1]+num[j]*num[k]*num[i+j-1]); } } /*for (i=1;i<=n-1;i++) { for (j=i;j<=n;j++) printf("%d ",f[i][j]); printf("\n"); }*/ printf("%d",f[1][n]); return 0; }